java - BroadcastReceiver onReceive 方法内的异步任务未运行?

标签 java android broadcastreceiver android-broadcastreceiver

我有一个正在运行的应用程序,它将字符串数据从应用程序的输入文本字段发送到我的 PC 上的 TCP 服务器。 我添加了 BroadcastReceiver 类,以便在收到消息时将消息发送到计算机。 应用程序接收消息(Toast 正在工作),但我无法让它将收到的消息发送到 PC。

没有错误。应用程序只是跳过调用的方法。

如何在onReceive中调用方法?

感谢您的帮助!

public class SmsReceiver extends BroadcastReceiver {
String phone;
String message;

@Override
public void onReceive(Context context, Intent intent) {
    Bundle intentExtras = intent.getExtras();

    if (intentExtras != null) {
        // Get Messages
        Object[] sms = (Object[]) intentExtras.get("pdus");

        for (int i = 0; i < sms.length; ++i) {
            // Parse Each Message
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);

            phone = smsMessage.getOriginatingAddress();
            message = smsMessage.getMessageBody().toString();
            System.out.println("Message is: "+message);
            Log.i("sth","message "+message);

            //What i have tried
            sendMessage(message);

            //creating instance
            MessageSender messageSender = new MessageSender();
            messageSender.execute(message);

            //calling metod from MainActivity
            ((MainActivity)context.getApplicationContext()).send2(message);

            MainActivity.send2(message);

            //toast is working fine
            Toast.makeText(context,"Alert:"+ phone + ": " + message, Toast.LENGTH_SHORT).show();
        }
    }
}
public void sendMessage(String s)
{
    MessageSender messageSender = new MessageSender();
    messageSender.execute(s);
}

主要 Activity

public class MainActivity extends AppCompatActivity {

EditText e1;

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    e1 = (EditText)findViewById(R.id.editText);
    //This works
    MessageSender messageSender = new MessageSender();
    messageSender.execute("App launched!");
}

//On Button click. Working good.
public void send(View v)
{
    MessageSender messageSender = new MessageSender();
    messageSender.execute(e1.getText().toString());
}
//For test purposes
public static void send2(String s)
{
    MessageSender messageSender = new MessageSender();
    messageSender.execute(s);
}

消息发送者

public class MessageSender extends AsyncTask<String,Void,Void>
{
Socket s;
DataOutputStream dos;
PrintWriter pw;

@Override
public Void doInBackground(String... voids) {

    String message = voids[0];
try {
    s = new Socket("192.168.1.69", 7800);
    pw = new PrintWriter(s.getOutputStream());
    pw.write(message);
    pw.flush();
    pw.close();
    s.close();

}catch(IOException e)
{
    e.printStackTrace();
}
    return null;
}

}

添加了服务器代码:

  public class MyServerFrame extends javax.swing.JFrame 
  {
  static Socket s;
   static ServerSocket ss;
  static InputStreamReader isr;
  static BufferedReader br;
  static String message;public MyServerFrame() 
 {

}

public static void main(String args[]) 
{   
    try 
    {
        ss = new ServerSocket(7800);
        while(true)
        {
            s=ss.accept();
            isr = new InputStreamReader(s.getInputStream());
            br = new BufferedReader(isr);
            StringBuilder everything = new StringBuilder();
            String line;
            while( (line = reader.readLine()) != null) 
            {
               everything.append(line);
            }
            message = everything.toString();//multiple to onelinestring 
            System.out.println(message);
        }   
    }catch (IOException e) 
    {
        e.printStackTrace();
    }
}

}

最佳答案

问题是,由于您在 onReceive 方法中使用异步任务执行网络请求,因此 onReceive 方法在 AsyncTask 执行之前返回,因为异步任务是异步的。因此,运行 onRequest 方法的进程将变为低优先级,因为 onReceive 方法已返回,并且操作系统将在异步任务实际执行之前终止它。

这里有两个解决方案:

首先确保您的 Android list 中声明了接收器,然后执行以下操作之一。

  1. 不要调用异步任务来执行网络请求,而是创建一个服务并使用该服务来运行网络代码。

  2. 您可以在 onReceive 方法中调用 goAsync() 方法来告诉系统给接收者更多的时间来执行其异步任务。其代码如下所示:

    @Override
    public void onReceive(final Context context, final Intent intent) {
    //create a pending intend that you will pass to the Async task so you can tell the system when the Async Task finished so that it can recycle.
    final PendingResult pendingResult = goAsync();
     AsyncTask<String, Integer, String> asyncTask = new AsyncTask<String,  Integer, String>() {
        @Override
        protected String doInBackground(String... params) {
            //put the network calling code in here
    
            // Must call finish() so the BroadcastReceiver can be recycled.
            pendingResult.finish();
            return data;
        }
    };
    asyncTask.execute();
     }
    

我认为第二种方法会更简单,所以我建议使用它,因为它不需要您创建一个全新的服务。

关于java - BroadcastReceiver onReceive 方法内的异步任务未运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49517983/

相关文章:

Android: LinearLayout addView 动画

android - 从广播接收器完成一个 Activity

Java:使用复制构造函数对具有 Runnable 成员的对象进行深度复制

java - 输入固定数字的最有效数据类型

java - C# 合约与 NotNull/在 Java 中创建自己的合约

Android Geofence 无法调用 IntentService 并且无法在 BroadcastReceiver 中工作

android - 如何在 android 中进行实时音频流时处理电话

java - 使用 jetty-runner 运行 Jetty 时更改端口

android - Android:在手机移动时播放音频时,耳机上会听到喀嗒声

java - 我如何允许在 android 中搜索也适用于字符重音?