通用的AsyncTask方法会干扰UI线程



在我的Android应用程序中构建并发HTTP服务的过程中,我遇到了一种很好的方法来处理由AsyncTask生成的结果,使用接口将ui活动注册为侦听器:

public interface Activity {
   void callback(String result);
}

AsyncTask类:

public class HTTP extends AsyncTask<String, Void, String> {
    private Activity activity;
    public HTTP(Activity activity) {
        this.activity = activity;
    }
    @Override
    protected String doInBackground(String... params) {
        try {
            URL url = new URL("http://" + params[0] + ":" + params[1] + "/" + params[2]);
            HttpURLConnection http = (HttpURLConnection) url.openConnection();
            http.setConnectTimeout(TIMEOUT);
            http.setRequestMethod("POST");
            http.setDoOutput(true);
            http.connect();
            ...
            return response;
        } catch (IOException e) {
            return "";
        }
    }
    @Override
    protected void onPostExecute(String result) {
        activity.callback(result);
    }
}

实际活动:

public class CreateActivity extends AppCompatActivity implements Activity {
    public void callback(String result) {
        if (result.isEmpty()) {
            toast(result);
        } else {
            Intent i = new Intent(this, ConfigActivity.class);
            startActivity(i);
            this.finish();
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_create);
    Button mCreateButton = (Button) findViewById(R.id.create_button);
    assert mCreateButton != null;
    mCreateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            host = mHostEditText.getText().toString();
            port = mPortEditText.getText().toString();
            data = mDataEditText.getText().toString();
            if (host.isEmpty() || port.isEmpty() || data.isEmpty()) {
                toast(ERR_EMPTY_FIELDS);
            } else {
                new HTTP(CreateActivity.this).execute(host, port, "ai", makeJson());
            }
        }
    });
}

根据logcat,这种方法仍然会阻塞调用线程近200帧,这对我来说是一个完全的谜。这个想法来源于这个repo:

https://github.com/levinotik/ReusableAsyncTask/tree/master/src/com/example

所以在执行了一些基准测试之后,我得出结论,挂起的线程是由makeJson()内部的加密设置引起的。

在我看来,唯一可以消耗大量时间的UI线程在你的代码是makeJson()方法。

但是你不应该在你的AsyncTask中保持对Activity的强引用,当Activity被重新创建(或销毁)时,你的AsyncTask可能仍在运行并持有对"死"Activity的引用。简单的解决方案是取消AsyncTask时,活动销毁。

相关内容

  • 没有找到相关文章

最新更新