AsyncTask的和弯针。prepare()错误错误、AsyncTask、prepare

2023-09-11 20:19:54 作者:EXO°青春无悔

我有以下的code

 类OverlayTask扩展的AsyncTask<虚空,虚空,虚空> {
    @覆盖
    在preExecute公共无效(){

        如果(网站!= NULL){
            。myMapView.getOverlays()删除(网站);
            myMapView.invalidate();
            站点=无效;
        }
    }

    @覆盖
    公共无效doInBackground(空...未使用){
            grabShipsWithLocation();
            返程(空);
    }

    @覆盖
    公共无效onPostExecute(作废不用){
        。myMapView.getOverlays()加(网站);
        myMapView.invalidate();
        isLoading = FALSE;
    }
}
 

这似乎很好地工作在一些测试设备,但我看到了很多出现在开发控制台上的错误。我似乎无法找出为什么以及在哪里把这个活套。prepare()。需要它?

  java.lang.ExceptionInInitializerError
在com.test.appname.FinderMain $ 1.gotLocation(FinderMain.java:286)
在com.test.appname.MyLocation $ GetLastLocation.run(MyLocation.java:89)
在java.util.Timer中的$ TimerImpl.run(Timer.java:289)
java.lang.RuntimeException的:所致。内螺纹已经不叫尺蠖prepare无法创建处理器()
在android.os.Handler< INIT>(Handler.java:121)
在android.os.AsyncTask $ InternalHandler< INIT>(AsyncTask.java:421)
在android.os.AsyncTask $ InternalHandler< INIT>(AsyncTask.java:421)
在android.os.AsyncTask< clinit>(AsyncTask.java:152)
 

根据要求MyLocation.java

 类GetLastLocation扩展的TimerTask {
    @覆盖
    公共无效的run(){
         lm.removeUpdates(locationListenerGps);
         lm.removeUpdates(locationListenerNetwork);

         位置net_loc = NULL,gps_loc = NULL;
         如果(gps_enabled)
             gps_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
         如果(network_enabled)
             net_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

         //如果有两个值,用最新一期
         如果(gps_loc = NULL和放大器;!&安培;!net_loc = NULL){
             如果(gps_loc.getTime()> net_loc.getTime())
                 locationResult.gotLocation(gps_loc);
             其他
                 locationResult.gotLocation(net_loc);
             返回;
         }

         如果(gps_loc!= NULL){
             locationResult.gotLocation(gps_loc); //行89
             返回;
         }
         如果(net_loc!= NULL){
             locationResult.gotLocation(net_loc);
             返回;
         }
         locationResult.gotLocation(空);
    }
}
 
AsyncTask研究 以Android 10.0为准

解决方案

龙的故事:

的AsyncTask 在内部使用处理程序。处理程序基本上可以让你发布的Runnable 从处理程序被分配到,它在案件的AsyncTask 总是从它被称为线程。这仅适用于具有尺蠖 prepared,虽然线程。

有关详细信息,请参阅http://developer.android.com/reference/android/os/Handler.html

简单地说:

简单地包装在一个的Runnable ,并将其张贴到处理程序绑定到UI线程,像这样的:

 类GetLastLocation扩展的TimerTask {
    私人处理程序mHandler =新的处理程序(Looper.getMainLooper());

    @覆盖
    公共无效的run(){
       // ...
       mHandler.post(新的Runnable(){
          公共无效的run(){
              locationResult.gotLocation(空);
          }
       });
       // ...
     }
}
 

I have the following code

class OverlayTask extends AsyncTask<Void, Void, Void> {
    @Override
    public void onPreExecute() {

        if (sites != null) {
            myMapView.getOverlays().remove(sites);
            myMapView.invalidate();
            sites = null;
        }
    }

    @Override
    public Void doInBackground(Void... unused) {
            grabShipsWithLocation();
            return (null);
    }

    @Override
    public void onPostExecute(Void unused) {
        myMapView.getOverlays().add(sites);
        myMapView.invalidate();
        isLoading = false;
    }
}

That seems to work fine on a few test devices but I am seeing a lot of errors appearing on the dev console. I can't seem to work out why and where to put this Looper.prepare(). Is it needed?

java.lang.ExceptionInInitializerError
at com.test.appname.FinderMain$1.gotLocation(FinderMain.java:286)
at com.test.appname.MyLocation$GetLastLocation.run(MyLocation.java:89)
at java.util.Timer$TimerImpl.run(Timer.java:289)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
at android.os.AsyncTask.<clinit>(AsyncTask.java:152)

As requested MyLocation.java

    class GetLastLocation extends TimerTask {
    @Override
    public void run() {
         lm.removeUpdates(locationListenerGps);
         lm.removeUpdates(locationListenerNetwork);

         Location net_loc=null, gps_loc=null;
         if(gps_enabled)
             gps_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
         if(network_enabled)
             net_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

         //if there are both values use the latest one
         if(gps_loc!=null && net_loc!=null){
             if(gps_loc.getTime()>net_loc.getTime())
                 locationResult.gotLocation(gps_loc);
             else
                 locationResult.gotLocation(net_loc);
             return;
         }

         if(gps_loc!=null){
             locationResult.gotLocation(gps_loc); //Line 89
             return;
         }
         if(net_loc!=null){
             locationResult.gotLocation(net_loc);
             return;
         }
         locationResult.gotLocation(null);
    }
}

解决方案

Long story:

AsyncTask internally uses a Handler. A handler basically allows you to post Runnables from another thread on the thread the handler was assigned to, which in the case of AsyncTask is always the thread from which it is called. This only works for threads that have a Looper prepared, though.

For more information see http://developer.android.com/reference/android/os/Handler.html

Short story:

Simply wrap every call to FinderMain$1.gotLocation or the creation of AsyncTask within it in a Runnable, and post it to a Handler bound to the UI thread, like this:

class GetLastLocation extends TimerTask {
    private Handler mHandler = new Handler(Looper.getMainLooper());

    @Override
    public void run() {
       // ...
       mHandler.post(new Runnable() {
          public void run() {
              locationResult.gotLocation(null);
          }
       });
       // ...
     }
}