Android:如果AsyncTask初始化(文件下载)失败,请关闭应用程序

时间:2015-09-16 09:52:05

标签: android android-asynctask

每次用户启动应用程序时,都会发生一些初始化阶段,涉及在AsyncTask中从Web下载文件。我需要监视在连接问题时启动App的情况并处理它:

  1. 如果下载已开始但未完成 - 可能会在下载完成时等待3秒 - 然后继续进行初始化过程。
  2. 如果在额外的3秒后下载未完成 - 请关闭App。
  3. 如果从一开始就没有开始下载 - 关闭应用程序。
  4. 我做了什么:

    public class Initialisation extends Activity {
    
        public boolean isDownloadStarted = false;
        public boolean isDownloadFinished = false;
    
        @Override
        public void onCreate(Bundle saved) {
            initFoo1();
            …
            new DownloadAsyncTask.execute();  //for the sake of simplicity assume it 
                                                takes “zero time” so if all OK it 
                                                should be ready in next line check
            ...
            initFooN();
            if (isDownloadFinished) {
                //continue regular
            }
            //if download started and not finished maybe it’s just slow connection
            //give 3 more seconds to succeed 
            else if (isDownloadStarted == true && isDownloadFinished == false) {
                showProgressSpinner();
                new SleepAsyncTask.execute();
            }
            //if download not started - Connection error - close App now
            else if (!isDownloadStarted) {
                exitProcess();
            }
        }
    
        public class DownloadAsyncTask extends AsyncTask<Void, Void, Void> {
            @Override
            public void doInBackground(Void… params) {
                isDownloadStarted = true;
                fooDownloadFile();   
                isDownloadFinished = true;
            }
        }
    
        public class SleepAsyncTask extends AsyncTask<Void, Void, Void> {
            @Override
            public void doInBackground(Void… params) {
                Thread.sleep(3000);
            }
            @Override
            public void onPostExecute(Void result) {
                if (isDownloadFinished) {
                    dismissProgressSpinner();
                    //TODO: Do nothing - Should be continue regular?
                }
                //if even after 3 more seconds the download not finished - close the App
                else {
                    exitProcess();
                }
            }
        }
    
        public void exitProcess() {
            //TODO: Is it the right way?
            this.finish();
            System.exit(0);
        }
    
    }
    

    我的问题是关于TODO以及整体而言 - 这种方法是否会成功,这是处理这种情况的好方法?

1 个答案:

答案 0 :(得分:2)

  1. 您在两个线程之间共享布尔变量 - 访问它们时应提供一些同步。从理论上讲,AsyncTask的线程会生成布尔值的副本,这种情况可能导致意外会议或不符合if语句中的条件。 在您的情况下,volatile关键字应该会有所帮助。您可以在此处详细了解(http://www.javamex.com/tutorials/synchronization_volatile.shtml)。

  2. 为什么你实际上使用AsyncTask? AsyncTasks的一个主要问题是取消了他们的工作。其次,它们经常导致应用程序中的内存泄漏。我建议使用IntentService来完成下载工作。

  3. 通过调用System.exit(0),您可以告诉VM明确重启您的进程。这是理想的行为吗?

  4. 如果在额外的3秒后下载未完成 - 请关闭App。

  5. 好吧,我不确定你是否意识到这一点,但是从Android HONEYCOMB开始,当没有明确告知以并行方式运行时,AsyncTasks会按顺序执行(http://developer.android.com/reference/android/os/AsyncTask.html - 执行顺序)。

    以下是IntentService使用示例 https://github.com/dawidgdanski/Bakery。如果下载不成功,要处理通知应用程序在3秒后退出的逻辑,请使用Handler.postDelayed。对于IntentService和您的活动之间的沟通,请使用BroadcastReceiver

    流速:

    1. 开始活动。调用Handler&#39; s.postDelayed()方法。开始服务。注册广播接收器,以便在下载作业完成后处理来自服务的广播。
    2. 如果下载在等待超时之前完成,remove all callbacks from Handler
    3. 否则在超时Runnable中调用finish()方法。
    4. 希望有所帮助。