带宽有限的长时间互联网操作

时间:2014-03-31 10:33:29

标签: android android-fragments android-asynctask

昨天我发布了我的应用程序,我在手机上测试并按预期工作。当我的朋友使用3G而不是WiFi下载它时,我的应用程序无法下载所有内容,因此它崩溃了。我使用了一个运行AsyncTask的无头片段来下载内容(这是一些照片),我的猜测是它花了很多时间拍摄一些照片并跳过它们,抛出一些时间例外。我的问题是,如果我使用服务运行我的AsyncTask并下载内容而不是片段,这是否可以避免?

  private ArrayList<Monument> processJsonData(JSONObject jsonObj) throws IOException{

  try{                  



    JSONArray posts=jsonObj.getJSONArray(TAG_POSTS);
    ArrayList<Monument> monuments = new ArrayList<Monument>();

    for (int i=0; i<posts.length(); i++){



            JSONArray attachments = c.optJSONArray(TAG_ATTACHMENTS);
            if(attachments!=null){
                int lengthSize;
                if(attachments.length()<3)
                    lengthSize=attachments.length();
                else
                    lengthSize=3;
                for(int j=0;j<lengthSize;++j){                              

                            JSONObject atta = attachments.getJSONObject(j); 
                            JSONObject images = atta.optJSONObject(TAG_IMAGES); 
                            if(images!=null){
                                JSONObject medium = images.getJSONObject(TAG_MEDIUM);
                                String url_image = medium.getString(TAG_URL_IMAGE);                                 
                                String  id = atta.getString("id");

                                String filename =title.replace(" ","")+id+".nomedia";
                                File destination = new File(MyApplication.getPhotoStorage() ,filename);

                                URL url = new URL (url_image);

                                InputStream is = url.openStream();
                                OutputStream os = new FileOutputStream(destination);


                                byte[] b = new byte[2048];
                                int length;

                                while ((length = is.read(b)) != -1) {
                                    os.write(b, 0, length);
                                }

                                is.close();
                                os.close();
                                localPhotosUrl.add(destination.getAbsolutePath());
                            }


               }
        }




    }

  } catch (Exception e) {
      e.printStackTrace();
  }
   return null;

  }

编辑所以我现在在代码中进行了这些更改我正在处理connectionTimeout异常,但我无法正常捕获

        @Override
    protected String doInBackground(String... args) {               


    JSONParser jParser = new JSONParser();
    JSONObject jsonObj = jParser.getJSONFromUrl(url);
    Log.d("check1",url);
    try {

        listOfObjects.addAll(processJsonData(jsonObj));
        } catch (Exception e) {
            e.printStackTrace();
            onDownloadFailed(this);
        } finally {
            jsonObj=null;
        }


        return "done"; 
    }

        protected void onDownloadFailed(downloadUrl task) {

        System.out.println(task.tag+" failed to download");
        if(dtask1.cancel(true))
            Log.d("TASK1", "Canceled");
        if(dtask2.cancel(true))
            Log.d("TASK2", "Canceled");
        if(dtask3.cancel(true))
            Log.d("TASK3", "Canceled");
        if(dtask4.cancel(true))
            Log.d("TASK4", "Canceled");

        mCallbacks.onDownloadFailed();

    }



  private ArrayList<Monument> processJsonData(JSONObject jsonObj) throws IOException, SocketException, JSONException{

            JSONArray attachments = c.optJSONArray(TAG_ATTACHMENTS);
            if(attachments!=null){
                int lengthSize;
                if(attachments.length()<3)
                    lengthSize=attachments.length();
                else
                    lengthSize=3;

                for(int j=0;j<lengthSize;++j){                              

                            JSONObject atta = attachments.getJSONObject(j); 
                            JSONObject images = atta.optJSONObject(TAG_IMAGES); 
                            if(images!=null){
                                JSONObject medium = images.getJSONObject(TAG_MEDIUM);
                                String url_image = medium.getString(TAG_URL_IMAGE);                                 
                                String  id = atta.getString("id");

                                String filename =title.replace(" ","")+id+".nomedia";
                                File destination = new File(MyApplication.getPhotoStorage() ,filename);

                                try{
                                    URL url = new URL (url_image);

                                    InputStream is = url.openStream();
                                    OutputStream os = new FileOutputStream(destination);


                                    byte[] b = new byte[2048];
                                    int length;

                                    while ((length = is.read(b)) != -1) {
                                        os.write(b, 0, length);
                                    }

                                    is.close();
                                    os.close();
                                    localPhotosUrl.add(destination.getAbsolutePath());

                                }catch (SocketException e) {
                                    throw new SocketTimeoutException();
                                }



                            }


               }
        }

2 个答案:

答案 0 :(得分:0)

没有。这是不可避免的。您不能指望连接持续很长时间。手机上可能发生任何事情(电池电量耗尽,网络信号丢失等)

您必须对应用进行编码,以便正确检查其是否具有所有可用资源,并重试(或更好地,恢复)失败的下载。

为了增加你的机会,在相对较小的下载而不是大文件中打破你的资源。然后,当使用3G时,用户不必从头开始全部下载。

答案 1 :(得分:0)

好吧,所以我不太了解JSON,但这不应该影响这个答案,我不会想。看起来您的问题可以通过better use of Exception handling来解决。

目前你根本没有真正处理异常,只是抓住它并打印堆栈跟踪。此外,因为整个方法都在一个try{ }语句中,所以如果在处理任何一个附件时出现问题,则该方法将退出。相反,您可以在try{ }循环中包含for块。这样,如果任何一个循环块失败(由于连接不稳定),您可以使用catch块j--;然后Thread.sleep(4000);。这样,当循环中抛出异常时它将被捕获,循环将被跳回以再次尝试相同的部分,并且将暂停以等待更好的连接。

示例(未测试);

for (int j = 0; j < lengthSize; ++j) {

    try{
        JSONObject atta = attachments.getJSONObject(j);
        JSONObject images = atta.optJSONObject(TAG_IMAGES);
        if (images != null) {
            JSONObject medium = images.getJSONObject(TAG_MEDIUM);
            String url_image = medium.getString(TAG_URL_IMAGE);
            String id = atta.getString("id");

            String filename = title.replace(" ", "") + id + ".nomedia";
            File destination = new File(MyApplication.getPhotoStorage(), filename);

            URL url = new URL(url_image);

            InputStream is = url.openStream();
            OutputStream os = new FileOutputStream(destination);


            byte[] b = new byte[2048];
            int length;

            while ((length = is.read(b)) != -1) {
                os.write(b, 0, length);
            }

            is.close();
            os.close();
            localPhotosUrl.add(destination.getAbsolutePath());
        } 
    }catch (Exception e){
         Thread.sleep(4000);
         j--;
    }
}

您可能还想创建一个计数器,以查看已尝试的次数。如果代码进行了太多尝试,那么您可以假设它永远不会工作并从方法返回。

我希望这会有所帮助。让我知道你是怎么过的。


另外,除此之外你永远不应该抓住Exception。最好能够捕获您期望的特定异常,以便您可以根据Exception子类型以不同方式处理它们。你可能不想抓住RunTimeException并试图在没有有效方法的情况下处理它。