通用AsyncTask方法会干扰UI线程

时间:2016-08-12 14:20:50

标签: java android user-interface concurrency android-asynctask

在我的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帧的调用线程,这对我来说完全是个谜。 这个想法来自这个回购:

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

提前致谢。

2 个答案:

答案 0 :(得分:0)

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

因此AsyncTask应该没问题。

答案 1 :(得分:0)

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

但是你不应该在AsyncTask中强烈引用Activity,当重新创建(或销毁)Activity时,你的AsyncTask仍然可以运行并保持对#34; dead&#34;活动。 Simples解决方案是在Activity正在销毁时取消你的AsyncTask。