Android应用程序冻结在工作线程中运行的代码

时间:2014-03-18 13:36:04

标签: java android multithreading handler freeze

我想在用户的位置发生变化时开始定期活动。所以我有一个位置监听器,它启动一个线程,这个线程将一个runnable发布到一个处理程序

public class GpsListener implements LocationListener {
private String TAG = "GpsListener";
private RefreshThread runnable = null;
private Thread thread = null;
private Context context = null;

public GpsListener(Context context) {
    // this.mapHandler = mapHandler;
    this.context = context;
}

@Override
public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub
    Log.i(TAG, "onLocationChanged");
    Log.i(TAG, "latitude: " + location.getLatitude() + "\n" + "longitude: "
            + location.getLongitude());

    TestThread t1 = new TestThread(location.getLatitude(),
            location.getLongitude(), context);
    Thread t = new Thread(t1);
    t.start();

    }
}


public class TestThread implements Runnable {
private Handler handler = new Handler();
private RefreshThread thread = null;// new RefreshThread();
private double latitude;
private double longitude;
private Context context;
private String TAG = "TestThread";

public TestThread(double latitude, double longitude, Context context) {
    this.latitude = latitude;
    this.longitude = longitude;
    this.context = context;
}

@Override
public void run() {
    // TODO Auto-generated method stub
    Log.i(TAG, "run");
    thread = new RefreshThread(latitude, longitude, context, handler);
    handler.removeCallbacks(thread);
    handler.post(thread);
    }

}

当线程开始时我希望它继续发布相同的runnable,直到再次调用testthread(我实际上并没有在位置监听器中停止testthread,但这不是我现在的问题)

public class RefreshThread implements Runnable {

private double latitude;
private double longitude;
private Handler handler = null;
private String TAG = "RefreshTread";
private int time = 10000;
private Context context = null;

public RefreshThread(double latitude, double longitude, Context context,
        Handler handler) {// ,
    // MapHandler
    // mapHandler) {
    this.longitude = longitude;
    this.latitude = latitude;
    // this.mapHandler = mapHandler;
    this.handler = handler;
    this.context = context;
}

@Override
public void run() {
    Log.i(TAG, "run");
    // while (true) {
    Log.i(TAG, "doing work");
    GetMapDataTask task = new GetMapDataTask();
    task.execute("asfasf#123", longitude + "#" + latitude);
    try {
        String response = task.get();
        Log.i(TAG, response);
        Bundle data = new Bundle();
        data.putDouble("longitude", longitude);
        data.putDouble("latitude", latitude);
        Intent intent = new Intent("updateMap");
        ArrayList<Point> points = new ArrayList<Point>();
        if (response != null && !response.equals("No POI")) {
            ArrayList<String> temppoints = new ArrayList<String>();
            while (response.contains("$")) {
                String[] tempar = response.split("\\$", 2);
                temppoints.add(tempar[0]);
                response = tempar[1];
            }
            temppoints.add(response);

            for (String temp : temppoints) {
                String[] tempar = temp.split("#");
                Point temppoint = new Point(Double.parseDouble(tempar[1]),
                        Double.parseDouble(tempar[0]), tempar[2], tempar[3]);
                points.add(temppoint);
            }
            // msg.obj = points;
        } else
            points = null;
        intent.putExtra("data", data);
        intent.putExtra("points", points);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
        // msg.obj = null;
        // mapHandler.sendMessage(msg);
        // Log.i(TAG, "finished work, going to sleep");
    } catch (InterruptedException e) {
        Log.i(TAG, "interrupted");
        e.printStackTrace();
        return;
        // TODO Auto-generated catch block
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    // }
    // TODO Auto-generated method stub
    handler.postDelayed(this, time);

}

}

和RefreshThrad启动尝试连接到Web服务的asynctask

public class GetMapDataTask extends AsyncTask<String, Object, String> {

private final String METHOD_NAME = "getMapData";
private final String NAMESPACE = "http://server/";
private final String WSDL_URL = "http://192.168.2.2:9999/POI/POIService?";
private String TAG = "GetMapDataTask";
private final String SOAP_ACTION = "\"http://server/getMapData\"";

@Override
protected String doInBackground(String... params) {
    // TODO Auto-generated method stub
    Log.i(TAG, "doInBackground");
    Log.i(TAG, params[0] + "," + params[1]);
    // String userInfo = params[0];
    SoapObject parameter = new SoapObject(NAMESPACE, METHOD_NAME);
    parameter.addProperty("user_data", params[0]);
    parameter.addProperty("position", params[1]);
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
            SoapEnvelope.VER11);
    envelope.setOutputSoapObject(parameter);

    // 3. Create an HTTP Transport object to send the web service request
    HttpTransportSE httpTransport = new HttpTransportSE(WSDL_URL, 30000);
    httpTransport.debug = true; // allows capture of raw request/respose in
                                // Logcat

    // 4. Make the web service invocation
    try {
        httpTransport.call(SOAP_ACTION, envelope);
    } catch (HttpResponseException e) {
        Log.i(TAG, "Error1");
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        Log.i(TAG, "Error2");
        e.printStackTrace();
        return "Error while connectiong to the server";
        // TODO Auto-generated catch block
    } catch (XmlPullParserException e) {
        Log.i(TAG, "Error3");
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // Logging the raw request and response (for debugging purposes)
    Log.d(TAG, "HTTP REQUEST:\n" + httpTransport.requestDump);
    Log.d(TAG, "HTTP RESPONSE:\n" + httpTransport.responseDump);
    String processedResponse = null;
    // 5. Process the web service response
    if (envelope.bodyIn instanceof SoapObject) { // SoapObject = SUCCESS
        SoapObject soapObject = (SoapObject) envelope.bodyIn;
        processedResponse = parseSOAPResponse(soapObject);
        // ... do whatever you want with this object now
    } else if (envelope.bodyIn instanceof SoapFault) { // SoapFault =FAILURE
        SoapFault soapFault = (SoapFault) envelope.bodyIn;
        processedResponse = soapFault.faultstring;
        try {
            throw new Exception(soapFault.getMessage());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    return processedResponse;
}
}

首先我尝试使用服务而不是测试线程,但我的应用程序挂在httpTransport.call(SOAP_ACTION,信封); 如果服务不可用(我根本没有启动它)30秒,因为 HttpTransportSE httpTransport = new HttpTransportSE(WSDL_URL,30000); 所以我试图使用testThread,这样就不会发生这种情况。但确实如此。

你能解释为什么这段代码会挂起我的应用程序吗?

1 个答案:

答案 0 :(得分:0)

您的处理程序在UI线程中运行,就像它创建它一样。

你的asynctask在它自己的线程中运行但是你在它上面调用了get(),这使得UI线程(Handler的线程)等到doInBackground()的结束

这是一种混乱的线程方式,为什么不运行asyncTask?