Помогите!Приложение ждет, пока закроется Force Force во втором запуске - PullRequest
0 голосов
/ 28 августа 2011

Я очень новичок в Android, и я собрал простое приложение для тестирования многоадресных пакетов в AsyncTask.

При первом запуске приложения все идет, как я ожидал, но если я закрою его и попытаюсь запустить его во второй раз, приложение просто зависнет, пока не запустится диалоговое окно принудительного закрытия.

После этого я снова могу запустить программу один раз и так далее. Я предполагаю, что есть что-то, что я не закрываю должным образом.

Я проверил logCat, но единственные сообщения, которые я получаю:

WARN/ActivityManager(1193): Activity idle timeout for HistoryRecord{45b352c0 android.projects.bserver/.BroadcastServer}
WARN/ActivityManager(1193): Activity pause timeout for HistoryRecord{45b352c0 android.projects.bserver/.BroadcastServer}

Если кто-нибудь скажет мне, что я делаю неправильно, что вызывает зависание во втором запуске, я был бы благодарен.

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import android.app.Activity;
import android.content.Context;
import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class BroadcastServer extends Activity {
public static final int PORT = 1200;
TextView textStatus;
String data = "this is a test";
public static boolean running = true;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    textStatus = (TextView)findViewById(R.id.writeBlock);

    textStatus.append("\nStarting");

    MyAsync ma = new MyAsync();
    ma.execute(data);
    textStatus.append("\nTaskRunning");
    /////////////////////////////////////////////
    try
    {
        InetAddress address = getBroadcastAddress();/////////
        InetAddress multiGroup = InetAddress.getByName("224.0.5.255");

        ///////////////////////////////time to receive

        MulticastSocket socket2 = new MulticastSocket(PORT);//////
        socket2.joinGroup(multiGroup);

        byte[] buf = new byte[1024]; 
        DatagramPacket packet2 = new DatagramPacket(buf, buf.length); 

        textStatus.append("\nWaiting to Receive");

        socket2.receive(packet2);

        textStatus.append("\nReceived");

        String received = new String(packet2.getData());

        textStatus.append("\n" + received);
        running = false;

        textStatus.append("\nFinished");

    }
    catch(IOException e)
    {
        textStatus.append("\nTaskFailed Outer: " + e.getMessage());
    }
    textStatus.append("\nProgramDone");
}

///////////////////////////////////////////////////

InetAddress getBroadcastAddress() throws IOException { 
    //Original Line: WifiManager wifi = mContext.getSystemService(Context.WIFI_SERVICE);
    WifiManager wifi = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);

    DhcpInfo dhcp = wifi.getDhcpInfo();
    // handle null somehow      
    int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;     
    byte[] quads = new byte[4];     
    for (int k = 0; k < 4; k++)       
        quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);     
    return InetAddress.getByAddress(quads); 
}

class MyAsync extends AsyncTask<String, Integer, String>
{
    @Override
    protected void onPreExecute()
    {
        textStatus.append("\nAsyncStarted");
    }

    @Override
    protected String doInBackground(String... params) {
        ///////////////////////////////time to send
        String data = params[0];

        try
        {
        InetAddress address = getBroadcastAddress();///////////////
        InetAddress multiGroup = InetAddress.getByName("224.0.5.255");

        MulticastSocket socket = new MulticastSocket(PORT);
        socket.setBroadcast(true); 
        socket.joinGroup(multiGroup);//////////
        DatagramPacket packet = new DatagramPacket(data.getBytes(), 
                data.length(), address, PORT); 

        //int count = 0;
        while(BroadcastServer.running)
        {
            socket.send(packet);  
            //publishProgress(count);
            //count++;
        }
        }
        catch(IOException e)
        {
            textStatus.append("\nTaskFailed Inner: " + e.getMessage());
        }

        return "AsyncDone";
    }

    @Override
    protected void onProgressUpdate(Integer... count)
    {
        textStatus.append("\n" + count.toString());
    }

    @Override
    protected void onPostExecute(String results)
    {
        textStatus.append("\n"+results);
    }
}
}

1 Ответ

2 голосов
/ 28 августа 2011

Во-первых, вы сказали, что принудительное закрытие, но я подозреваю, что вы видите не закрытие принудительного вызова, а приложение, не отвечающее (ANR), которое совсем другое. ANR - это не сбой, это означает, что ваше приложение связано с чем-то трудоемким в потоке пользовательского интерфейса.

Вы делаете сетевой вызов в потоке пользовательского интерфейса. Вы переместили некоторые в AsyncTask, но вам нужно получить все, что связано с сетью, из потока пользовательского интерфейса. Если вы закомментируете сетевой код, ваше приложение снова будет отзывчивым.

В качестве общего совета вы можете также узнать о IntentService, который является еще одним подходом к выделению действий, выполняемых в фоновом режиме.

...