BroadcastReceiver onReceive 方法中的异步任务不是 运行?

Async Task inside BroadcastReceiver onReceive method not running?

我有一个工作应用程序,它可以将字符串数据从应用程序的输入文本字段发送到我电脑上的 TCP 服务器。 我添加了 BroadcastReceiver class 以在收到消息时将消息发送到计算机。 应用程序接收消息(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);
}

主要活动

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 方法 returns 在 AsyncTask 执行之前执行,因为异步任务是异步的。因此,运行onRequest 方法的进程变为低优先级,因为 onReceive 方法已返回并且操作系统将在异步任务实际执行之前将其终止。

这里有两种解决方法:

首先确保接收方已在您的 Android 清单中声明,然后执行以下操作之一。

  1. 与其调用异步任务来执行您的网络请求,不如创建一个服务并将该服务用于 运行 网络代码。

  2. 可以在onReceive方法中调用goAsync()方法,告诉系统给接收者更多的时间去执行它的Async Task。代码如下:

    @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();
     }
    

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

感谢 SteelToe 引导我找到这个简单的解决方案:

Receiver was not declared in manifest file.