i am implementing Watson Assistant v2 asynchronous request (with no thread, as it is not required). but i end up with crash for making network call on main thread. which means this call is not called asynchronous on android.
"android.os.NetworkOnMainThreadException" - This exception is thrown when an application attempts to perform a networking operation on its main thread
code:-
public void sendMessage(String message){
Log.d("TAG","message :"+message+", session id:"+sessionId);
MessageInput input = new MessageInput.Builder()
.messageType("text")
.text(message)
.build();
MessageOptions options = new MessageOptions.Builder(assistanID, sessionId)
.input(input)
.build();
assistant.message(options).enqueue(new ServiceCallback<MessageResponse>() {
@Override
public void onResponse(MessageResponse response) {
System.out.println(response);
Gson gson = new Gson();
GsonWatson gsonparse = gson.fromJson(String.valueOf(response), GsonWatson.class);
mainActivity.messageRecievedFromAssistant(gsonparse.getOutput().getGeneric().get(0).getText());
}
@Override
public void onFailure(Exception e) {
}
});
}
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
at okhttp3.Dns$1.lookup(Dns.java:40)
at okhttp3.internal.connection.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:185)
at okhttp3.internal.connection.RouteSelector.nextProxy(RouteSelector.java:149)
at okhttp3.internal.connection.RouteSelector.next(RouteSelector.java:84)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:214)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
at okhttp3.RealCall.execute(RealCall.java:77)
at com.ibm.watson.developer_cloud.service.security.IamTokenManager.callIamApi(IamTokenManager.java:187)
at com.ibm.watson.developer_cloud.service.security.IamTokenManager.requestToken(IamTokenManager.java:108)
at com.ibm.watson.developer_cloud.service.security.IamTokenManager.getToken(IamTokenManager.java:78)
at com.ibm.watson.developer_cloud.service.WatsonService.setAuthentication(WatsonService.java:375)
at com.ibm.watson.developer_cloud.service.WatsonService.createCall(WatsonService.java:206)
at com.ibm.watson.developer_cloud.service.WatsonService.createServiceCall(WatsonService.java:240)
at com.ibm.watson.developer_cloud.assistant.v2.Assistant.message(Assistant.java:151)
at com.XXX.IBMwatson.sendMessage(IBMwatson.java:78)
at com.XXX.ibmwatson.MainActivity$onCreate$1.onClick(MainActivity.kt:39)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
- did some digging in source code of Watson service. one of call which is made in background is run on main thread
class: XXX\files-2.1\com.ibm.watson.developer_cloud\core\6.13.2\673b89ba561c095131da91c327c99800f12b6d9f\core-6.13.2-sources.jar!\com\ibm\watson\developer_cloud\service\security\IamTokenManager.java
method: callIamApi:187
line:187:- okhttp3.Response response = call.execute();
this call is made on main thread.
This is currently a bug in the Java SDK where, as you pointed out, the call to authenticate through IAM is still made on the main thread. This bug is currently documented here.
In the meantime, as a workaround, you can explicitly wrap the call in a new thread. One way to do this is with an
AsyncTask. Below is an example:where you just call it like this: