当UI线程等待AsyncTask时,应用程序崩溃

时间:2014-04-25 13:44:33

标签: java android multithreading android-asynctask futuretask

我正在Android中创建一个应用程序,当用户收到新的短信(SMS)时,它首先在服务器上发送,如果服务器回复为真,则广播中止,否则我们广播它。

现在问题是我们无法在UI线程上与服务器通信,所以为了克服这个问题,我们必须使用某种线程来执行后台操作,因此我使用AsyncTask与服务器进行通信。这是我的代码:

  

Android App:

public class IncomingSms extends BroadcastReceiver {

// Get the object of SmsManager
final SmsManager sms = SmsManager.getDefault();
public static String message;

public void onReceive(final Context context, Intent intent) {

    // Retrieves a map of extended data from the intent.
    final Bundle bundle = intent.getExtras();
    String senderNum;
    try {

        if (bundle != null) {

            final Object[] pdusObj = (Object[]) bundle.get("pdus");

            for (int i = 0; i < pdusObj.length; i++) {

                SmsMessage currentMessage = SmsMessage
                        .createFromPdu((byte[]) pdusObj[i]);
                String phoneNumber = currentMessage
                        .getDisplayOriginatingAddress();

                senderNum = phoneNumber;
                message = currentMessage.getDisplayMessageBody();
                CallServer callServer = new CallServer();
                callServer.execute();
                Log.d("textmsg", callServer.getStatus().toString());

                /*
                  while (callServer.getStatus().toString() == "RUNNING") {
                  //Log.d("textmsg", "working in loop"); }
                 */

                if(callServer.get() == "true")
                    abortBroadcast();

                Log.d("textmsg", callServer.getStatus().toString() + "done");

                // Show Alert
                Toast toast = Toast.makeText(context, "senderNum: "
                        + senderNum + ", message: " + message,
                        Toast.LENGTH_LONG);
                toast.show();

            } // end for loop
        } // bundle is null

    } catch (Exception e) {
        Log.e("SmsReceiver", "Exception smsReceiver" + e);

    }
}

private class CallServer extends AsyncTask<String, String, String> {
    @SuppressLint("NewApi")
    protected String doInBackground(String... arg0) {
        Socket socket = null;
        DataOutputStream dataOutputStream = null;
        DataInputStream dataInputStream = null;

        try {
            socket = new Socket("192.168.1.100", 8081);
            Log.d("textmsg", "connected");
            dataOutputStream = new DataOutputStream(
                    socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());
            if (!message.isEmpty()) {
                dataOutputStream.writeBytes(message);

                return (dataInputStream.readBoolean() == true) ? "true"
                        : "false";
            }
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            Log.e("error", e.toString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.e("error", e.toString());
        }

        return "false";
    }

     @Override protected void onPostExecute(String result){

         Log.d("textmsg", result);

     }

}
}

我无法理解的问题是每当我使用callServer.get()while (callServer.getStatus().toString() == "RUNNING"){}我的应用程序崩溃时,我这样做是因为我必须等待服务器回复i.e: true or false所以如果服务器回复我可以中止广播。

LogCat:
D/textmsg(29494): RUNNING
D/textmsg(29494): connected
I/dalvikvm(29399): threadid=3: reacting to signal 3
I/dalvikvm(29494): Wrote stack traces to '/data/anr/traces.txt'

注意:当我的应用程序在服务器上发送请求时,我的服务器端代码工作正常。 我还通过创建简单的客户端服务器应用程序来测试我的服务器端代码 我的服务器在我的本地计算机上运行,​​因此我没有任何网络问题。

我也尝试过FutureTask但是我遇到了同样的问题。 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

这就是你不想使用.get()的原因。这实际上会阻止您的主用户界面等待AsyncTask执行的结果,因此您的应用将获得ANR。不要使用它。

相反,在您将onPostExecute()方法处理为某个Activity变量后,请分配结果。

答案 1 :(得分:1)

callServer.get()调用get块ui线程等待结果。你永远不应该阻止ui线程。您无需致电get()。调用get()将使其不再异步。

callServer.execute()调用doInBackground即可。