android 版本 < 4 的异步任务问题

Asynctask issue on android version < 4

我开发了一个支持 android os 4 及更高版本的应用程序。我在应用程序启动期间使用 Asynctask 进行 Web 服务调用。

后来我将 minSdkVersion 更改为 9。以支持 android 2.3 及更高版本。但是相同的代码会抛出以下错误。

从 SplashActivity 线程调用 AsyncTask

  mSplashTread = new Thread() {           @Override           public void run() {
          try {
              int waited = 0;
              while (mActive && (waited < mSplashTime)) {
                  sleep(100);
                  if (mActive) {
                      waited += 100;
                  }
              }
          } catch (InterruptedException e) {
              AppUtil.getInstance().logErrorMessage(TAG, e.getMessage());
          } finally {
              if (mIsBackPressed) {
                  finish();
              } else {
                  GetMobilePremissionWebservice getMobilePermissionWebservice = new GetMobilePremissionWebservice(
                          mContext, SplashActivity.this);
                  getMobilePermissionWebservice.getMobilePermissionInfo();
              }
          }           }       };

日志:

Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.(Handler.java:121) at android.os.AsyncTask$InternalHandler.(AsyncTask.java:421) at android.os.AsyncTask$InternalHandler.(AsyncTask.java:421)

我在网上查过了。有人说 Asynctask 内部使用 Handler。当它试图从 doInBackgrond() 访问 UI 时。 但相同的代码在 os 4 及更高版本中运行良好。我不知道 Android 版本 2.3 上的 Asynctask 有什么问题。

请帮我解决这个问题。

尝试在执行后更新 UI 而不是 doInBackground。 仅在 doInBackground 中获取数据,然后在执行后使用该数据来更新 UI.

也就是说你必须在主线程上调用AsyncTask.execute(...)方法。

虽然前一句话在技术上不正确,但 99% 的时间都是预期的行为。毕竟您使用异步任务将计算从主线程卸载到后台线程。如果您已经在后台线程中,则不需要异步任务,对吗?

因为进行服务调用的正确格式如下。尝试按照以下格式进行网络服务调用

private class AsyncCallWS extends AsyncTask<Void, Void, Void> 
{
    @Override
    protected void onPreExecute() 
    {
        super.onPreExecute();
        //show progress dialog
    }

    @Override
    protected Void doInBackground(Void... params) 
    {
        try 
        {
            postData();
        }
        catch (Exception e) 
        {
            // TODO: handle exception
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) 
    {

        //dismiss progress dialog
    }
}

    public void postData()
    {
        Thread t = new Thread() 
        {
            public void run()
            {
                Looper.prepare(); 
                HttpClient httpclient = new DefaultHttpClient();    
                HttpPost httppost = new HttpPost("http://yourURL");

                try
                {
                    // Your webservice code......

                }
                catch (ClientProtocolException e)
                {
                 e.printStackTrace();
                }
                catch (IOException e)
                {
                 e.printStackTrace();
                }
                catch (JSONException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Looper.loop(); //Loop in the message queue
            }
        };
        t.start();  
    } 

}

这将解决您的错误...

实际上问题是我从线程调用 Asynctask。

通过使用 runOnUiThread,我从线程调用 Asynctask 解决了我的问题。

mSplashTread = new Thread() {
            @Override
            public void run() {
                try {
                    int waited = 0;
                    while (mActive && (waited < mSplashTime)) {
                        sleep(100);
                        if (mActive) {
                            waited += 100;
                        }
                    }
                } catch (InterruptedException e) {
                    AppUtil.getInstance().logErrorMessage(TAG, e.getMessage());
                } finally {
                    if (mIsBackPressed) {
                        finish();
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                GetMobilePremissionWebservice getMobilePermissionWebservice = new GetMobilePremissionWebservice(
                                        mContext, SplashActivity.this);
                                getMobilePermissionWebservice
                                        .getMobilePermissionInfo();
                            }
                        });
                    }
                }
            }
        };

但我仍然不知道为什么相同的代码在 android 版本 4.2 Samsung s3 中工作。