Android:AsyncTask 未达到 onPostExecute
Android : AsyncTask not reaching onPostExecute
我正在使用 AsyncTask 来避免我的 Android 库项目出现 networkonmainthreadexception,现在我想做的是将要 return 的值赋给我的变量并在执行之前等待它下一行代码。我用 CountDownLatch 来做这个。
我执行请求和调用 AsyncTask 的方式写在下面。所以我使用 CountDownLatch 来等待响应,然后 returning 我想要 return 的值。
public MyObject getMyObject(){
final String url = "http://[myip]:8080/retrieve";
try{
Response response = executeRequest(url);
final MyObject myObject = om.readValue(response.body().string(),
new TypeReference<MyObject>() {
});
return myObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Response executeRequest(String url){
try {
//Simplified please just ignore this..
GenericAsyncParams genericAsyncParams = createParams(......);
final CountDownLatch countDownLatch = new CountDownLatch(1);
ResponseListener responseListener = new ResponseListener(countDownLatch);
MyAsyncTask myAsyncTask = new AsyncTask(responseListener);
myAsyncTask.execute(genericAsyncParams);
countDownLatch.await();
//get the response from the listener class.
Response response = responseListener.getResponse();
return response;
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
我也知道 asyncTask.execute(args).get() 可能会导致异常,所以我使用了一个监听器来更新调用者的值,我在我的 AsyncTask 的 onPostExecute 上调用 setResponse。
public class ResponseListener {
private static final String TAG = ResponseListener.class.getName();
private Response response;
private CountDownLatch countDownLatch;
public ResponseListener(CountDownLatch countDownLatch) {
this.response = null;
this.countDownLatch = countDownLatch;
}
public void setResponse(Response response){
this.response = response;
Log.e(TAG, "Executing countdown..");
countDownLatch.countDown();
}
public Response getResponse() {
return response;
}
public CountDownLatch getCountDownLatch() {
return countDownLatch;
}
}
现在这是我的 AsyncTask
注意:requestProcessor 是 okHttp 的包装器 class。
public class MyAsynctask extends AsyncTask<GenericAsyncParams, Void, Response>{
private static final String TAG = MyAsyncTask.class.getName();
private ResponseListener listener;
public MyAsynctask(ResponseListener listener) {
this.listener = listener;
}
@Override
protected Response doInBackground(GenericAsyncParams... genericAsyncParamses) {
Response response = null;
GenericAsyncParams genericAsyncParams = genericAsyncParamses[0];
String url = genericAsyncParams.getUrl();
String method = genericAsyncParams.getMethod();
RequestProcessor requestProcessor = genericAsyncParams.getRequestProcessor();
try {
Request.Builder builder;
if(method.equalsIgnoreCase("POST")){
builder = new Request.Builder()
.post(genericAsyncParams.getRequestBody())
.url(url)
.headers(headers);
} else {
builder = new Request.Builder()
.headers(headers)
.get()
.url(url);
}
final Request request = builder.build();
response = requestProcessor.client().newCall(request).execute();
Log.d(TAG, "returning okHttp response..");
return response;
} catch (Exception e){
Log.e(TAG, String.format("ERROR.. %s", ExceptionUtils.getMessage(e)));
}
return response;
}
@Override
protected void onPostExecute(Response response) {
if(listener != null){
Log.d(TAG, "Updating response : onPostExecute..");
listener.setResponse(response);
} else {
super.onPostExecute(response);
}
}
}
我日志的最后一行是
07-10 23: 47:07.008 28409-28530/com.aaron.android.android.lib D/com.aaron.android.android.lib.api.tasks.MyAsyncTask: returning okHttp response..
NetworkOnMainException
提醒我们不要阻塞主线程 UI。但是,您仍然通过使用 CountDownLatch
等待响应来阻止它。由于 onPostExecute()
在主线程上运行,因此您已阻止它执行。在等待网络连接完成时,您不能阻塞主线程。相反,允许 executeRequest()
到 return 以便 UI 可以适当地响应。
我正在使用 AsyncTask 来避免我的 Android 库项目出现 networkonmainthreadexception,现在我想做的是将要 return 的值赋给我的变量并在执行之前等待它下一行代码。我用 CountDownLatch 来做这个。
我执行请求和调用 AsyncTask 的方式写在下面。所以我使用 CountDownLatch 来等待响应,然后 returning 我想要 return 的值。
public MyObject getMyObject(){
final String url = "http://[myip]:8080/retrieve";
try{
Response response = executeRequest(url);
final MyObject myObject = om.readValue(response.body().string(),
new TypeReference<MyObject>() {
});
return myObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Response executeRequest(String url){
try {
//Simplified please just ignore this..
GenericAsyncParams genericAsyncParams = createParams(......);
final CountDownLatch countDownLatch = new CountDownLatch(1);
ResponseListener responseListener = new ResponseListener(countDownLatch);
MyAsyncTask myAsyncTask = new AsyncTask(responseListener);
myAsyncTask.execute(genericAsyncParams);
countDownLatch.await();
//get the response from the listener class.
Response response = responseListener.getResponse();
return response;
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
我也知道 asyncTask.execute(args).get() 可能会导致异常,所以我使用了一个监听器来更新调用者的值,我在我的 AsyncTask 的 onPostExecute 上调用 setResponse。
public class ResponseListener {
private static final String TAG = ResponseListener.class.getName();
private Response response;
private CountDownLatch countDownLatch;
public ResponseListener(CountDownLatch countDownLatch) {
this.response = null;
this.countDownLatch = countDownLatch;
}
public void setResponse(Response response){
this.response = response;
Log.e(TAG, "Executing countdown..");
countDownLatch.countDown();
}
public Response getResponse() {
return response;
}
public CountDownLatch getCountDownLatch() {
return countDownLatch;
}
}
现在这是我的 AsyncTask 注意:requestProcessor 是 okHttp 的包装器 class。
public class MyAsynctask extends AsyncTask<GenericAsyncParams, Void, Response>{
private static final String TAG = MyAsyncTask.class.getName();
private ResponseListener listener;
public MyAsynctask(ResponseListener listener) {
this.listener = listener;
}
@Override
protected Response doInBackground(GenericAsyncParams... genericAsyncParamses) {
Response response = null;
GenericAsyncParams genericAsyncParams = genericAsyncParamses[0];
String url = genericAsyncParams.getUrl();
String method = genericAsyncParams.getMethod();
RequestProcessor requestProcessor = genericAsyncParams.getRequestProcessor();
try {
Request.Builder builder;
if(method.equalsIgnoreCase("POST")){
builder = new Request.Builder()
.post(genericAsyncParams.getRequestBody())
.url(url)
.headers(headers);
} else {
builder = new Request.Builder()
.headers(headers)
.get()
.url(url);
}
final Request request = builder.build();
response = requestProcessor.client().newCall(request).execute();
Log.d(TAG, "returning okHttp response..");
return response;
} catch (Exception e){
Log.e(TAG, String.format("ERROR.. %s", ExceptionUtils.getMessage(e)));
}
return response;
}
@Override
protected void onPostExecute(Response response) {
if(listener != null){
Log.d(TAG, "Updating response : onPostExecute..");
listener.setResponse(response);
} else {
super.onPostExecute(response);
}
}
}
我日志的最后一行是
07-10 23: 47:07.008 28409-28530/com.aaron.android.android.lib D/com.aaron.android.android.lib.api.tasks.MyAsyncTask: returning okHttp response..
NetworkOnMainException
提醒我们不要阻塞主线程 UI。但是,您仍然通过使用 CountDownLatch
等待响应来阻止它。由于 onPostExecute()
在主线程上运行,因此您已阻止它执行。在等待网络连接完成时,您不能阻塞主线程。相反,允许 executeRequest()
到 return 以便 UI 可以适当地响应。