停止 AsyncTask 会导致服务结束

Posted

技术标签:

【中文标题】停止 AsyncTask 会导致服务结束【英文标题】:Stopping AsyncTask causes Service to end 【发布时间】:2012-04-04 01:26:06 【问题描述】:

我有一个运行两个异步任务的服务。一个用于接收组播数据包,另一个用于接收 udp 数据包。我已经注册了一个 wifi 状态监听器,并希望在与接入点的连接丢失时停止监听数据包。但是当我尝试关闭任何一个套接字并尝试结束 while 循环时,服务本身就会关闭。我希望该服务在我的活动退出之前一直运行。 以下是我的代码的相关部分。括号可能放错了...

public class ReceiveService extends Service 

private Receive r;
private ReceiveMulticast rm;
private boolean running = true;

private boolean receive = false, receivemulti = false;


@Override
public IBinder onBind(Intent arg0) 
    // return binder;
    return null;


@Override
public void onCreate() 

    try 

        r = new Receive();
        rm = new ReceiveMulticast();


        if (wifi.checkwifi(this)) //check if connected to access point
            wifiInit();
            receive();
            receivemulti();
        

     catch (Exception e) 
        Log.d("test", "exception in oncreate");
        //e.printStackTrace();
    



public void wifiInit() 
    wm = wifi.getWifiManager(this);
    myip = wifi.getmyip(wm);
    wifi.acquirelock(wm);


public void receive() 
    r.execute();
    receive = true;



public void receivemulti() 
    rm.execute();
    receivemulti = true;



private BroadcastReceiver WifiStateChangedReceiver = new BroadcastReceiver() 

    @Override
    public void onReceive(Context context, Intent intent) 

        //monitor changes in wifi state
    
;

@Override
public void onDestroy() 
    try 
        if (!r.ds1.isClosed())
            r.ds1.close();
        if (!rm.s.isClosed()) 
            rm.s.leaveGroup(rm.group);
            rm.s.close();
        

        super.onDestroy();
     catch (Exception e) 
        Log.d("test", "Exception in destroy");
    


private class Receive extends AsyncTask<Void, String, Void> 

    private DatagramSocket ds1;
    private DatagramPacket p;

    protected void onPreExecute() 

    

    protected Void doInBackground(Void... params) 

        try 
            ds1 = new DatagramSocket(7777);
         catch (SocketException e) 
            Log.d("test", "Exception in new datagram");
            //e.printStackTrace();
        
        int buffer_size = 1024;
        byte buffer1[] = new byte[buffer_size];
        p = new DatagramPacket(buffer1, buffer1.length);

        while (running) 
            try 
                ds1.receive(p);
                String sip = p.getAddress().getHostAddress();
                String rec = new String(p.getData(), 0, p.getLength());

                //publishProgress(sip + "+" + rec);
             catch (Exception e) 

                running = false;
            
        
        return null;

    

    protected void onProgressUpdate(String... progress) 
        //do stuff

    

    protected void onPostExecute(Void result) 
        stopSelf();
    



private class ReceiveMulticast extends AsyncTask<Void, String, Void> 

    private String ip = "224.0.0.10";
    private int port = 6789;
    private MulticastSocket s;
    private DatagramPacket mp;
    private InetAddress group;

    protected void onPreExecute() 

    

    protected Void doInBackground(Void... params) 

        try 
            group = InetAddress.getByName(ip);
            s = new MulticastSocket(port);
            s.joinGroup(group);
         catch (UnknownHostException e1) 
            Log.d("test", "exception unknown host rm");

            //e1.printStackTrace();
         catch (IOException e) 
            Log.d("test", "exception io rm");

            //e.printStackTrace();
        

        byte[] buffer2 = new byte[1024];
        mp = new DatagramPacket(buffer2, buffer2.length);

        while (running) 

            try 
                s.receive(mp);
                String sip = mp.getAddress().getHostAddress();
                String rec = new String(mp.getData(), 0, mp.getLength());

                //publishProgress(sip + "+" + rec);
             catch (Exception e) 

                running = false;

            
        
        return null;
    

    protected void onProgressUpdate(String... progress) 

        //do stuff


        

    

    protected void onPostExecute(Void result) 
        stopSelf();
    



【问题讨论】:

【参考方案1】:

正常停止还是异常停止?

您正在 AsyncTask 之一的 postExecute() 中调用 stopSelf()。如果您遇到异常,您的 while(true) ... 循环将退出,然后调用 postExecute(),它调用 stopSelf()。这可能是原因,但由于您没有记录异常,因此无法知道。

【讨论】:

感谢您为我指明正确的方向。我从某个地方复制了 asynctask 模板,但没有意识到 stopself() 是用于停止服务而不是任务。完全忽略了它。再次感谢。你为我节省了很多时间......【参考方案2】:

AsyncTask 只能在 UI 线程上运行。

【讨论】:

以上是关于停止 AsyncTask 会导致服务结束的主要内容,如果未能解决你的问题,请参考以下文章

C# Async Await 注意事项

android asynctask 导致另一个活动

Android学习之AsyncTask

获得致命异常:使用 Async 类的 AsyncTask #1

如何将 Asynctask 用于位图?

什么是生命周期感知方式来实现重复的AsyncTask?