繁体   English   中英

如何不使用AsyncTask和不使用库在Android中实现长时间运行的网络上传

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM