调试了好久,才发现是因为Http请求写在了主线程里,在4.0之后在主线程里面执行Http请求都会报这个错,大概是怕Http请求时间太长造成程序假死的情况吧。
//于是我改写了函数,在函数里面创建了线程调用网络请求,但函数return值返回是空的,估计是线程还未执行完就返回了,我是一名android初学者,想请教一下各位,怎样改写下面这个函数,我想在程序其它地方直接调用 GetJSonData(),就得到我想要的返回结果。
public String GetJSonData() { String responseJSON = ""; new Thread(new Runnable() { @Override public void run() { responseJSON = TO DO http request. } }).start(); return responseJSON; }
你的分析是对的,这里需要异步返回。线程内完成后,给ui线程post一个event。new Handler(Looper.mainLooper()).postRunnable(...)
异步任务想要使用直接返回,可以使用kotlin的协程。
java无法做到,java只能等到异步任务结束后,通过接口或者其它方式回调
网络请求等耗时操作需要花一定时间才能得到结果,所以用返回值的方式是不行的。一般都在请求成功后通过回调函数将结果传递出来。
这里涉及一个同步与异步的问题,开启线程执行网络请求,java是按照顺序从上往下执行的,除非使用 Thread.sleep(); 等函数卡住主线程,不然的话,如同上图代码,启动线程,然后下一步就到了 return responseJSON;这里了,这时候线程里没执行完,结果还没返回赋值给 responseJSON,所以导致返回时空的。这里应该改造一下,等网络请求结束再返回数据。
可以使用Handler 或者 接口回调等,例如:
public interface OnResultCallBack {
void onResultCallBack(String responseJSON);
}
public void GetJSonData(OnResultCallBack callBack) {
new Thread(new Runnable() {
@Override
public void run() {
String responseJSON = TO DO http request;
callBack. onResultCallBack(responseJSON);
}
}).start();
}