0

我正在 Android 中创建一个应用程序,其中每当用户收到新的文本消息 (SMS) 时,它首先在服务器上发送,如果服务器回复 true,则广播被中止,否则我们广播它。

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

安卓应用:

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 但是我遇到了同样的问题。任何帮助将不胜感激。

4

2 回答 2

2

这就是为什么你不想使用.get(). 这实际上会阻止您的主 UI 等待AsyncTask执行结果,因此您的应用程序将获得ANR. 不要使用它。

相反,一旦你完成了onPostExecute()对 someActivity变量的方法的处理,就将结果分配。

于 2014-04-25T13:46:27.677 回答
1

callServer.get()调用 get 会阻塞等待结果的 ui 线程。你永远不应该阻塞 ui 线程。你不需要打电话get()。调用get()将不再使其异步。

callServer.execute()调用doInBackground就足够了。

于 2014-04-25T13:46:35.243 回答