[英]Android Model-View-Presenter(MVP) How to Return Long-Running AsyncTask
[英]How to implement long-running network uploads in Android not using AsyncTask and not using libraries
无需使用RoboSpice之类的库即可实现长时间运行的网络操作(例如上传一堆照片)的Android本机方法是什么?
我已经阅读了很多关于stackoverflow的主题,这些建议表明asynctask不适合长时间运行的操作,因为它与活动的生命周期紧密相关,可能会导致内存泄漏,并且由于android 3.2的存在,因此一个应用程序的所有asynctasks只有一个线程。 (不确定最后一个)
如何用其他东西代替我的asynctask?
现在,我听说过处理程序,执行程序,服务以及其他内容,但是如何在代码中准确实现它们以及选择哪个呢?
这是我使用的asynctask的示例
我删除了很多代码,只是为了您可以看到基本结构
public class UploadPhotosToServer extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... args) {
HashMap<String, String> params = new HashMap<String, String>();
try {
if(uploadImageToServer(id, path, params)) {
success = true;
} else {
success = false;
}
} catch (Exception e) {
e.printStackTrace();
success = false;
}
return success;
}
public boolean uploadImageToServer(int imageId, String imagePath, HashMap<String, String> params) throws Exception {
try {
JSONObject json = jsonParser.uploadImageToServer(imagePath, params);
JSONObject message = json.getJSONObject("message");
String serverResponse = message.getString("success");
if (serverResponse.contentEquals("true") {
return true;
} else {
return false;
}
} catch (JSONException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
这是jsonParser.uploadImageToServer
public JSONObject uploadImageToServer(String imagePath, HashMap<String, String> params) throws Exception {
HttpResponse response;
MultipartEntityBuilder multipartEntity;
HttpPost postRequest;
HttpContext localContext;
Bitmap bitmap;
try {
// Set the http handlers
httpClient = new DefaultHttpClient();
localContext = new BasicHttpContext();
postRequest = new HttpPost(SERVER + "images");
// Send the package
multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("file", new FileBody(new File(imagePath)));
for (Map.Entry<String, String> entry : params.entrySet()) {
multipartEntity.addTextBody(entry.getKey(), entry.getValue());
}
postRequest.setEntity(multipartEntity.build());
// Get the response. we will deal with it in onPostExecute.
response = httpClient.execute(postRequest, localContext);
HttpEntity httpEntity = response.getEntity();
inputStream = httpEntity.getContent();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
json = sb.toString();
inputStream.close();
reader.close();
} catch (ClientProtocolException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
// Try parsing the string to a JSON object
try {
jsonObject = new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
}
// Return JSON String
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
我认为对于一组上传,我会考虑实现IntentService 。 如链接中所述,它将处理工作线程中的意图列表,直到该列表用尽为止,此时服务将再次关闭。
IntentService
的实现非常简单。 一个基于您上面给出的示例的示例;
public class ImageUploadIntentService extends IntentService {
public ImageUploadIntentService() {
super("ImageUploadIntentService");
}
@Override
public void onCreate() {
// Not a required implementation but you might want to setup any dependencies
// here that can be reused with each intent that the service is about to
// receive.
super.onCreate();
}
@Override
public void onHandleIntent(Intent intent) {
// Process your intent, this presumably will include data such as the local
// path of the image that you want to upload.
try {
uploadImageToServer(intent.getExtra("image_to_upload"), params);
} catch (Exception e) {
// Oh :( Consider updating any internal state here so we know the state
// of play for later
}
}
public JSONObject uploadImageToServer(String imagePath, HashMap<String, String> params) throws Exception {
// All of your upload code
}
}
然后调用服务就这么简单;
Intent intent = new Intent(this, ImageUploadIntentService.class)
.putExtra("image_to_upload", mImagePath);
startService(intent);
这确实给我们带来了指示您的上传队列进度的问题。 我们可以使用ResultReceiver解决这个问题。 结果接收器是可Parcelable
因此我们可以有意发送它,以便侦听我们可能感兴趣的结果。您可以使用“ Activity
和适当的进度对话框来处理ResultReceiver
,或者如果您希望使用进度条,然后您可以使用Service
来托管接收器。
它比使用AsyncTask
涉及的更多,但是它确实为您提供了更多的灵活性,并且不像Activity生命周期那样重要。 使用IntentService
另一个IntentService
它仍只会使您成为一个工作线程,因此图像上传不会同时发生。 但是我可能会考虑将位图JPEG压缩分解为它自己的IntentService
然后在上载第一个图像的同时对队列中的下一个图像进行压缩。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.