简体   繁体   中英

Asynctask slow down issue

I'm trying to check existence of 2000 files in Asynctask. In the initial execution, it works well. But if I restart app about 10 times , loading speed slows down. As I am a beginner developer, I lack understanding of Asynctask. Please give me some advices.

This is my splash activity

public class SplashActivity extends AppCompatActivity {
    getFirstData gfd;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        gfd = new getFirstData(this, (TextView) findViewById(R.id.textView18));
        gfd.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, this);
    }

    @Override
    protected void onDestroy() {
        try
        {
            if (gfd.getStatus() == AsyncTask.Status.RUNNING)
            {
                gfd.cancel(true);
            }
            else
            {
            }
        }
        catch (Exception e)
        {
        }
        super.onDestroy();
    }
}

And this is my asynctask code

public class getFirstData extends AsyncTask<Context,Integer,Void> {
    private PowerManager.WakeLock mWakeLock;
    private Context context;
    private TextView textview;
    getFirstData(Context context,TextView tv){
        this.context=context;
        this.textview=tv;
    }
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        PowerManager pm = (PowerManager) this.context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
        mWakeLock.acquire();
    }

    @Override
    protected Void doInBackground(Context...contexts) {
        Database.addDB();
        for (int i = 0; i < Database.db_list.size(); i++) {
            File filetemp = Database.getFilename(i, ".pdf", Database.db_list);
            if (filetemp.exists()) {
                Database.db_list.get(i).isDownloaded = true;
            }
            publishProgress(Database.db_list.size(),i);
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... params) {
        super.onProgressUpdate(params);
        textview.setText("Load("+params[1]*100/params[0]+"%)");
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        Intent intent = new Intent(this.context, MainActivity.class);
        this.context.startActivity(intent);
        ((Activity)this.context).finish();
    }
}

AsyncTask cancel method doesn't immediately stop your AsyncTask , instead it'll only 'cancel' after doInBackground completes. ( Reference )

Calling this method will result in onCancelled(java.lang.Object) being invoked on the UI thread after doInBackground(java.lang.Object[]) returns. Calling this method guarantees that onPostExecute(Object) is never subsequently invoked, even if cancel returns false, but onPostExecute(Result) has not yet run. To finish the task as early as possible, check isCancelled() periodically from doInBackground(java.lang.Object[]) .

If you want your AsyncTask to end as quickly as possible, just make a check every 10 (or whatever value you deem suitable) iterations. Something along the following lines should work.

    @Override
    protected Void doInBackground(Context...contexts) {
        Database.addDB();
        for (int i = 0; i < Database.db_list.size(); i++) {
            File filetemp = Database.getFilename(i, ".pdf", Database.db_list);
            if (filetemp.exists()) {
                Database.db_list.get(i).isDownloaded = true;
            }
            publishProgress(Database.db_list.size(),i);
            if (i%10==0 && isCancelled()) {
                break;
            }
        }
        return null;
    }

I see you actually read the manual! Good work!

While its a good effort, unfortunately, the basic approach really just won't work.

I'm not completely clear on what is making the app slow down. If by "restart" you mean back-arrow and then start from the Desktop, then in is probably because you have many downloads running at once. Note that there is no way to stop your AsyncTask once you start it: cancel doesn't actually do anything, unless you implement it.

Your AsyncTask has all the typical problems with leaking a context (Studio is probably yelling at you about this already: pay attention). There is no reason to believe that the Activity that starts the task is still there when the task completes.

My suggestion is that you separate the state of the app from the Activity that views that state. This approach has lots of names but usually something like ViewModel. The View model is some kind of singleton that only allows users to see the Splash page until its state changes (it has the files downloaded). Then it shows the MainActivity .

Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM