为了账号安全,请及时绑定邮箱和手机立即绑定

Android AsyncTask线程限制?

Android AsyncTask线程限制?

千巷猫影 2019-09-19 14:29:31
我正在开发一个应用程序,我需要在每次用户登录系统时更新一些信息,我也在手机中使用数据库。对于所有这些操作(更新,从数据库中检索数据等),我使用异步任务。到目前为止,我不明白为什么我不应该使用它们,但最近我经历过,如果我做一些操作,我的一些异步任务只是停止预执行而不跳转到doInBackground。这样做太奇怪了,所以我开发了另一个简单的应用程序,只是为了检查什么是错误的。奇怪的是,当总异步任务的计数达到5时,我得到相同的行为,第6个在预执行时停止。android是否在Activity / App上有asyncTasks的限制?或者它只是一些错误,应该报告?有没有人遇到同样的问题,也许找到了解决方法?这是代码:只需创建其中5个线程即可在后台运行:private class LongAsync extends AsyncTask<String, Void, String>{    @Override    protected void onPreExecute()    {        Log.d("TestBug","onPreExecute");        isRunning = true;    }    @Override    protected String doInBackground(String... params)    {        Log.d("TestBug","doInBackground");        while (isRunning)        {        }        return null;    }    @Override    protected void onPostExecute(String result)    {        Log.d("TestBug","onPostExecute");    }}然后创建这个线程。它将进入preExecute并挂起(它不会进入doInBackground)。private class TestBug extends AsyncTask<String, Void, String>{    @Override    protected void onPreExecute()    {        Log.d("TestBug","onPreExecute");        waiting = new ProgressDialog(TestActivity.this);        waiting.setMessage("Loading data");        waiting.setIndeterminate(true);        waiting.setCancelable(true);        waiting.show();    }    @Override    protected String doInBackground(String... params)    {        Log.d("TestBug","doInBackground");        return null;    }    @Override    protected void onPostExecute(String result)    {        waiting.cancel();        Log.d("TestBug","onPostExecute");    }}
查看完整描述

3 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

如果您正在寻找一个简单的解决方案,那么您可以查看Needle。


有了它,你可以定义一个自定义线程池大小,不同AsyncTask,它适用于所有 Android版本相同。有了它你可以说:


Needle.onBackgroundThread().withThreadPoolSize(3).execute(new UiRelatedTask<Integer>() {

   @Override

   protected Integer doWork() {

       int result = 1+2;

       return result;

   }


   @Override

   protected void thenDoUiRelatedWork(Integer result) {

       mSomeTextView.setText("result: " + result);

   }

});

或类似的东西


Needle.onMainThread().execute(new Runnable() {

   @Override

   public void run() {

       // e.g. change one of the views

   }

}); 

它甚至可以做得更多。在GitHub上查看。


查看完整回答
反对 回复 2019-09-19
?
慕斯709654

TA贡献1840条经验 获得超5个赞

自API 19以来,核心线程池大小已更改,以反映设备上的CPU数量,启动时最小值为2,最大值为4,同时增加到最大CPU * 2 +1 - 参考


// We want at least 2 threads and at most 4 threads in the core pool,

// preferring to have 1 less than the CPU count to avoid saturating

// the CPU with background work

private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));

private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;

另请注意,虽然AsyncTask的默认执行程序是串行的(一次执行一个任务,并按照它们到达的顺序执行),但使用方法


public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,

        Params... params)

您可以提供执行程序来运行您的任务。您可以在引擎盖下执行THREAD_POOL_EXECUTOR但不进行任务序列化,或者您甚至可以创建自己的Executor并在此处提供。但是,请仔细注意Javadocs中的警告。


警告:允许多个任务从线程池并行运行通常不是您想要的,因为它们的操作顺序没有定义。例如,如果这些任务用于修改任何共同的状态(例如由于单击按钮而编写文件),则无法保证修改的顺序。如果没有仔细的工作,在较少的情况下,较新版本的数据可能会被较旧版本覆盖,从而导致模糊的数据丢失和稳定性问题。这些变化最好连续执行; 为了保证这些工作是序列化的,无论平台版本如何,您都可以将此功能与SERIAL_EXECUTOR一起使用。


还有一点需要注意的是,框架提供的执行程序THREAD_POOL_EXECUTOR及其串行版本SERIAL_EXECUTOR(AsyncTask的默认设置)都是静态的(类级别构造),因此跨应用程序进程的所有AsyncTask实例共享。


查看完整回答
反对 回复 2019-09-19
  • 3 回答
  • 0 关注
  • 537 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信