【问题标题】:Can't call handler in an AsyncTask?不能在 AsyncTask 中调用处理程序?
【发布时间】:2011-02-01 08:34:40
【问题描述】:

我想创建一个后台线程(即使我的活动终止也执行)更新我的数据位置并使用 http 请求将其发送到我的服务器。但是出现异常:

02-01 07:50:18.172: ERROR/Exception1(277): Can't create handler inside thread that has not called Looper.prepare()

我的代码:

public class Messagerie extends Activity {
private LocationManager locationManager;
private String locationProvider = LocationManager.NETWORK_PROVIDER;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.messagerie);

    new UpdateLocation().execute();

}

public void majCoordonnes() {
    StringBuilder stringBuilder = new StringBuilder("Fournisseur :");
    stringBuilder.append("\n");
    stringBuilder.append(locationProvider);
    stringBuilder.append(" : ");
    Location location = locationManager.getLastKnownLocation(locationProvider);

    if (location != null) {

        double latitude = location.getLatitude();
        double longitude = location.getLongitude();

        String lat = String.valueOf(latitude);
        String lon = String.valueOf(longitude);

        stringBuilder.append(latitude);
        stringBuilder.append(", ");
        stringBuilder.append(longitude);


                    //Send location to server in an AsyncTask
        new sendLocation().execute(lat, lon);


    } else {
        stringBuilder.append("Non déterminée");
    }
    Log.d("MaPositionMaj", stringBuilder.toString());
}


/**
 * Ecouteur utilisé pour les mises à jour des coordonnées
 */
class MajListener implements android.location.LocationListener {
    public void onLocationChanged(Location location) {
        majCoordonnes();
    }
    public void onProviderDisabled(String provider){
    }
    public void onProviderEnabled(String provider){
    }
    public void onStatusChanged(String provider, int status, Bundle extras){
    }
};




//Requête GET, mise à jour des infos
private class UpdateLocation extends AsyncTask<String, Void, String> {

    String resp;

    @Override
    protected String doInBackground(String... params) {

        try {
        //Recuperation Location
        String locationContext = Context.LOCATION_SERVICE;
        locationManager = (LocationManager) getSystemService(locationContext);
        if (locationManager != null && locationProvider != null) {

            majCoordonnes();
            locationManager.requestLocationUpdates(locationProvider, 120000, 500, new MajListener());


        }
        } catch (Exception e){
            Log.e("Exception1", e.getMessage());
        }

        return resp;
    }


    @Override
    protected void onPostExecute(String result) {


    }


    @Override
    protected void onPreExecute() {
    // Things to be done before execution of long running operation. For example showing ProgessDialog
    }


    @Override
    protected void onProgressUpdate(Void... values) {

    }
}

编辑:我认为我必须使用 Service 而不是 asyncTask。

【问题讨论】:

  • @user40574:您好,请用更清楚的方式解释您的问题,您的 Logcat 是否有任何期望或前台线程未能更新数据???????????? ?????????/
  • 我刚刚用 logcat 更新了我的帖子。

标签: android multithreading android-asynctask handler


【解决方案1】:

编辑:我认为我必须使用 Service 而不是 asyncTask。

没错。创建单独的线程并不能确保在应用程序/活动退出时,或者操作系统需要更多资源时它不会被杀死。 Service 也不能确保 - 如果系统负载非常重,它仍然可能会被杀死,但可能性要小得多。另外(如果我错了,请纠正我),一旦系统负载变软,Android 将重新启动服务。

【讨论】:

  • 使用 Timer(developer.android.com/reference/java/util/Timer.html) 代替服务怎么样?
  • @Flo 我看不出Timer 会有什么帮助。它不会阻止 Android 杀死你的进程。
  • 嗯,我认为 Timer 可以看作是一个 cron 作业对象,它可以让我定期触发一些功能,并且即使应用程序没有运行,它也可以调用此功能。我脑子里有一些东西,比如广播接收器,它可以启动一个活动,尽管这个活动的应用程序没有运行。那么 Timer 是直接绑定到应用程序上的吗?那你当然是对的,这并不能解决这个问题。
  • @Flo 是的,Timer 绑定到当前进程。您可以从BroadcastReceiver 开始Activity,但需要有人先致电您的BroadcastReceiver。对于你想要做的事情,我认为AlarmManager 最适合。您可以查看以下我写的关于非常相似的博客文章,我认为这会对您有所帮助:it-ride.blogspot.com/2010/10/…
  • 哦,好吧,然后我把 AlarmManager 和 Timer 混为一谈了。对此感到抱歉。感谢您的澄清。
【解决方案2】:

在运行Thread 之前,只需调用(写在代码中)Looper.prepare()。 (这是一个简单的解决方案,但以前也让我很奇怪。)

如果你不能调用你的Activity中的Handler,那么首先,你应该做你的活动构造函数,例如:

public SampleActivity() {
    super();
    // TODO Auto-generated constructor stub
}

然后在您的ASyncTask 中启动Activity

SampleActivity sampleAct = new SampleActivity();

最后一脚是打电话给你的Handler

sampleAct.handler.sendMessage(msg);

我希望这可以清楚地向您解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 2011-04-06
    • 2013-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多