Reputation: 1300
I have a threading problem with Android okhttp Websockets. I am doing a chat application, where I need to write and read from our server using websocket.
I read in other posts that with Okhttp, I should use StrictMode.ThreadPolicy.Builder().permitAll() as it has some issues etc. I added it.
But I keep getting this error when I try to sendMessage:
W/System.err: android.os.NetworkOnMainThreadException 09-13 17:13:32.198 22766-22766/com.microsoft.translator
Note that I am sending Message on a different thread, not on main thread.
Here is my code. Appreciate any help.
create websocket :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_chat);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
// lot other init stuff
createWebSocket();
}
private void createWebSocket() {
okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(WSS_URL + token)
.build();
webSocketCall = WebSocketCall.create(okHttpClient, request);
webSocketCall.enqueue(this);
}
@Override
public void onOpen(WebSocket webSocket, Response response) {
try {
Log.d(TAG, "onOpen: " + response.message());
String message = createJsonMessage("Hello");
byte[] messageBytes = message.getBytes();
showToastOnUIThread("OnOpen sending message");
webSocket.sendMessage(WebSocket.PayloadType.TEXT, new Buffer().write(messageBytes));
this.webSocket = webSocket;
//startRepeatingTask();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendMessage(final String msgString) {
Runnable postMessageThread = new Runnable() {
@Override
public void run() {
String message = createJsonMessage(msgString);
byte[] messageBytes = message.getBytes();
try {
if (webSocket != null) {
try {
webSocket.sendMessage(WebSocket.PayloadType.TEXT, new Buffer().write(messageBytes));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(ChatActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
ex.printStackTrace();
Toast.makeText(ChatActivity.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
postMessageThread.run();
}
Upvotes: 2
Views: 3859
Reputation: 307
I think this code is a simple example. If you don't use token to auth, you can remove addHeader.
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("your_name_input", "your_value")
.build();
Request request = new Request.Builder()
.url("your_url")
.post(requestBody)
.addHeader("name_your_token", "your_token")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String yourResponse = response.body().string();
if(response.isSuccessful()){
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Ok: "+yourResponse,Toast.LENGTH_SHORT).show();
}
});
}else{
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "Ok: "+yourResponse,Toast.LENGTH_SHORT).show();
}
});
}
}
});
And you also add permission in manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Upvotes: 2
Reputation: 2954
I think your code should be like this:
new Thread(new Runnable() {
public void run() {
// call send message here
}
}).start();
Or you can use Asyntask
Upvotes: 1