Async Task是下载1 mb以上文件的最佳选择

时间:2015-05-13 07:45:02

标签: android android-asynctask background-process

我在Android上运行一个图书服务应用程序,用户将图书下载到他的设备上。图书文件是1mb及以上。 可以将异步任务视为此类操作的最佳实践。 是否有其他方法可以在后台线程中执行下载。 请建议。

1 个答案:

答案 0 :(得分:1)

通常认为AsyncTask不适用于长时间运行的任务,但有时它是执行简单任务的简单方法(无论需要多长时间)。但问题是,一些开发人员以错误的方式执行它。

public class MainActivity extends Activity {

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // Somewhere the AsyncTask is started

    public class MyAsyncTask extends AsyncTask<Void, Void, String> {

        @Override protected String doInBackground(Void... params) {
            // Do work
            return result;
        }

        @Override protected void onPostExecute(String result) {
            Log.d("MyAsyncTask", "Received result: " + result);
        }
    }
}

上面代码的问题是,当您在Activity中启动AsyncTask并旋转设备或发生任何配置更改时,Activity将被销毁并创建一个新实例。但AsyncTask不会死并继续运行直到它完成。
问题
1)由于活动很繁重,如果启动了几个AsyncTask,这可能会导致内存问题。 2)另一个问题是AsyncTask的结果可能会丢失,如果它打算对活动的状态采取行动。
所以我们需要解决两个问题
1)框架销毁时不应将活动保存在记忆中 2)AsyncTAsk的结果应该传递给当前的活动实例 要解决这些问题,我们需要 otto http://square.github.io/otto/

使用otto创建MyBus.java,我们必须将其用作单身人士

public class MyBus {

    private static final Bus BUS = new Bus();

    public static Bus getInstance() {
        return BUS;
    }
}


创建AsyncTaskResultEvent.java文件

public class AsyncTaskResultEvent {

    private String result;

    public AsyncTaskResultEvent(String result) {
        this.result = result;
    }

    public String getResult() {
        return result;
    }
}


现在,在您的MainActivity中,执行AsyncTask

public class MyAsyncTask extends AsyncTask<Void, Void, String> {

    @Override protected String doInBackground(Void... params) {
        Random random = new Random();
        final long sleep = random.nextInt(10);
        try {
            Thread.sleep(sleep * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Slept for " + sleep + " seconds";
    }

    @Override protected void onPostExecute(String result) {
        MyBus.getInstance().post(new AsyncTaskResultEvent(result));
    }
}


现在,启动AsyncTask的Activity将在稍后获得结果。
要修复内存泄漏问题,请在MainActivity中添加以下代码

@Override protected void onDestroy() {
        MyBus.getInstance().unregister(this);
        super.onDestroy();
    }

    @Subscribe public void onAsyncTaskResult(AsyncTaskResultEvent event) {
        Toast.makeText(this, event.getResult(), Toast.LENGTH_LONG).show();
    }


并将这行代码放在OnCreate方法中
MyBus.getInstance().register(this);
现在如果发生配置更改,我们将自动通知新Activity实例中的结果,因为它已注册到事件总线。