即使AsyncTask处理任务,主UI也会冻结

Roh*_*ish 4 service android android-asynctask

Service在背景上运行,从互联网收集数据并使用AsyncTask它们存储Shared Preferences.即使完成工作AsyncTask仍然冻结了我的主要活动.

以下是服务代码:

public class GetterService extends Service {

    SharedPreferences.Editor editor;
    HashMap<Integer,String> links = new HashMap<Integer,String>();

    @Override
    public void onCreate() {
        editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
        populateLinks();
    }

    private void populateLinks(){
        // Here I add links to HashMap
    }

    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(this, "GetterService ON BIND", Toast.LENGTH_LONG).show();
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "GetterService ON DESTROY", Toast.LENGTH_LONG).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        doTasks();

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Toast.makeText(this, "GetterService ON UNBIND", Toast.LENGTH_LONG).show();
        return super.onUnbind(intent);
    }

    private void doTasks(){
        for (Integer in : links.keySet()) {

            Document doc = null;

            try {
                doc = new NetTask().execute(links.get(in)).get();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            if (doc != null) {
                Elements names = doc.select("strong, li");

                if(names != null && names.size() > 0) {
                    for (int j = 0; j < names.size(); j++) {
                        editor.putString("header"+j, names.get(j).text().toString());
                    }
                }
                editor.commit();
            }
        }   
    }

    public class NetTask extends AsyncTask<String, Integer, Document>
    {
        @Override
        protected Document doInBackground(String... params)
        {
            Document doc = null;
            try {
                doc = Jsoup.connect(params[0]).timeout(5000).get();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return doc;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我如何从主要活动开始服务:

Intent startServiceIntent = new Intent(this, GetterService.class);
        this.startService(startServiceIntent);
Run Code Online (Sandbox Code Playgroud)

Sam*_*Sam 8

即使工作是在AsyncTask中完成的,它仍然会冻结我的主要活动.

您正在使用get():

doc = new NetTask().execute(links.get(in)).get();
Run Code Online (Sandbox Code Playgroud)

get()在UI线程,直到的AsyncTask完成块,对我来说这种方法违背了使用的AsyncTask的目的...


你应该移动这个逻辑:

if (doc != null) {
    Elements names = doc.select("strong, li");

    if(names != null && names.size() > 0) {
        for (int j = 0; j < names.size(); j++) {
            editor.putString("header"+j, names.get(j).text().toString());
        }
    }
    editor.commit();
}
Run Code Online (Sandbox Code Playgroud)

在你NetTaskonPostExecute()方法里面并删除get().现在你的AsyncTask不会绑定主线程.