简体   繁体   English

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

[英]Application crashes when UI thread waits for AsyncTask

I am creating an application in Android in which whenever a user receives new Text message (SMS) it is first sent on server and if server replies true the Broadcast is aborted else we Broadcast it. 我正在Android中创建一个应用程序,在该应用程序中,每当用户收到新的文本消息(SMS)时,该消息首先在服务器上发送,并且如果服务器答复为true,则广播将中止,否则我们将对其进行广播。

Now the problem is we can not communicate with server on UI thread, so to overcome this problem we have to use some kind of thread to perform background operations, therefore I am using AsyncTask to communicate with server. 现在的问题是我们无法在UI线程上与服务器通信,因此要解决此问题,我们必须使用某种线程来执行后台操作,因此我正在使用AsyncTask与服务器进行通信。 Here is my code: 这是我的代码:

Android App: Android应用程式:

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);

     }

}
}

The problem which I can not understand is that whenever I use callServer.get() or while (callServer.getStatus().toString() == "RUNNING"){} my application crashes I am doing this because I have to wait for server reply ie: true or false so if server replies true I can abort the broadcast. 我无法理解的问题是,每当我使用callServer.get()while (callServer.getStatus().toString() == "RUNNING"){}我的应用程序就会崩溃,因为我必须等待服务器回复, ie: true or false因此,如果服务器回复为true,我可以中止广播。

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'

Note: My Server Side code is working perfectly as I receive message when my application sends request on server. 注意:当我的应用程序在服务器上发送请求时,我收到消息时,我的服务器端代码运行正常。 I have also tested my server side code by creating simple client server application. 我还通过创建简单的客户端服务器应用程序测试了服务器端代码。 My server is running on my local machine so I don't have any network issue. 我的服务器正在本地计算机上运行,​​因此我没有任何网络问题。

I have also tried FutureTask however I was facing same problem. 我也尝试过FutureTask,但是我遇到了同样的问题。 Any help would be greatly appreciated. 任何帮助将不胜感激。

And that's why you don't want to use .get() . 这就是为什么您不想使用.get() This will actually block your main UI waiting for the result of the AsyncTask execution, so your app will get ANR . 这实际上将阻止您的主UI等待AsyncTask执行的结果,因此您的应用程序将获得ANR Don't use it. 不要使用它。

Instead, assign the result once you're done processing your onPostExecute() method to some Activity 's variable. 相反,在完成onPostExecute()方法的处理后,将结果分配给一些Activity的变量。

callServer.get() calling get blocks the ui thread waiting for the result. 调用get的callServer.get()会阻止ui线程等待结果。 You should never block the ui thread. 您永远不应阻塞ui线程。 You need not call get() . 您无需调用get() Calling get() will make it asynchronous no more. 调用get()将使其不再异步。

callServer.execute() invokes doInBackground which is enough. callServer.execute()调用doInBackground就足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM