WiFi网络掉线后如何解决被系统杀死的app?

时间:2019-02-24 09:02:37

标签: android

我正在创建用于与TCP套接字服务器通信的Android应用。 TCP服务器是ESP8266 WiFi模块。应用程序和服务器每隔1秒钟就有一次通信,但我发现2个问题。

  1. WiFi网络断开后,应用被系统杀死
  2. 应用只能运行8分钟,并且会导致与1相同的问题

TCP任务代码

public class SingleControlWiFiModule extends AsyncTask<String[], Task, Task>{

private static final int CONNECT_TIMEOUT = 5000;
private static final int RESPONSE_TIMEOUT = 5000;
private int connectionTimeout, responseTimeout;
private String[] request;
//TCP
private Network network;
//Interface
private OnSingleResult result;
//Other
private static final String ERR_CON = "Connection Timeout!";
private static final String ERR_RES = "Response Timeout!";
public static final String ERR_OTHER = "System Error";
private static final String TAG = "SingleControl";

public SingleControlWiFiModule(Network network, OnSingleResult result){
    this.network = network;
    this.result = result;
    this.connectionTimeout = CONNECT_TIMEOUT;
    this.responseTimeout = RESPONSE_TIMEOUT;
}

public void startTask(String ip, String[] request){
    if (ip==null | request==null){ return; }
    //Must create New SingleControlWiFiModule object before Call This function
    this.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, new String[]{ip}, request);
}


private String[] getResponse(Socket socket, String[] request){
    try {
        // Create PrintWriter object for sending messages to server.
        PrintWriter outWrite = new PrintWriter(new BufferedWriter(
                new OutputStreamWriter(socket.getOutputStream())), true);
        //Send message
        for (String c : request){
            outWrite.print(c+",");
        }
        outWrite.flush();
        Log.w(TAG, "Send request success :: "+ Arrays.toString(request));
        //Create object for receiving message response from server.
        InputStreamReader inputStream = new InputStreamReader(socket.getInputStream());
        long start = System.currentTimeMillis(); boolean timeout = false;
        //Waiting
        while (!inputStream.ready()){
            timeout = (System.currentTimeMillis() - start)>responseTimeout;
            if (timeout){
                return new String[]{ERR_RES};
            }
        }
        //Reset start time
        start = System.currentTimeMillis();
        //Read response message
        StringBuilder s = new StringBuilder("");
        int i = 0; String []buffer = new String[Constant.BUFF_MAX];
        while (inputStream.ready()){
            //Int value
            int a = inputStream.read();
            //Convert int to char
            char data = (char)a;
            //Check value
            if (a>255){ data = '\0'; } //Empty
            //Check syntax ',' mean ending each word. So Server must send Ex: Hello,You,
            if (data==','){
                buffer[i] = s.toString(); ///Add message to String array
                s = new StringBuilder(""); ///Clear string
                i++;
            }else {
                s.append(data); //Create word string
            }
            //Check Timeout
            timeout = (System.currentTimeMillis() - start)>responseTimeout;
            if (timeout && !inputStream.ready()){ return new String[]{ERR_RES}; }
        }
        buffer = i > 0 ? Arrays.copyOf(buffer, i) : new String[]{s.toString()}; //Re-size buffer
        Log.w(TAG, "Server response :: " + Arrays.toString(buffer));
        return buffer;
    } catch (SocketTimeoutException e){
        e.printStackTrace();
        return new String[]{ERR_CON};
    } catch (IOException e) {
        e.printStackTrace();
        return new String[]{ERR_OTHER};
    }

}


@Override
protected Task doInBackground(String[]... strings) {

    request = strings[1];
    final String host = strings[0][0];
    Log.w(TAG, "Try connect: "+host+" By timeout connection: "+connectionTimeout+" response: "+responseTimeout);

    final Socket socket = new Socket();
    try {
        network.bindSocket(socket);
        socket.setKeepAlive(false);
        socket.setTcpNoDelay(true);
        socket.connect(new InetSocketAddress(host, Constant.PORT), connectionTimeout);

        //Get response
        Task task = new Task(host, Constant.PORT, request, getResponse(socket, request));

        //Disconnect server
        socket.close();
        //Return result
        return task;
    } catch (SocketTimeoutException e){
        e.printStackTrace();
        return new Task(host, Constant.PORT, request, new String[]{ERR_CON});
    } catch (IOException e) {
        e.printStackTrace();
        return new Task(host, Constant.PORT, request, new String[]{ERR_OTHER});
    }
}

@Override
protected void onPostExecute(Task task) {
    super.onPostExecute(task);
    if (task!=null){
        Log.w(TAG, "Finish :: request: "+Arrays.toString(task.request)+" response: "+Arrays.toString(task.response));
        if (result!=null){
            result.onFinish(task);
        }
    }

}

interface OnSingleResult{
    void onFinish(Task task);
}

}

MainAcivity

@Override
protected void onStart() {
    super.onStart();

    conManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkRequest.Builder wifiBuilder = new NetworkRequest.Builder();
    wifiBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
    if (conManager!=null && Function.isConnectWifi(this)){
        conManager.requestNetwork(wifiBuilder.build(), networkCallback);
    }else {
        statusText.setText(R.string.no_network);
        statusText.setVisibility(View.VISIBLE);
    }

}

@Override
protected void onStop() {
    super.onStop();

    //Stop loop reading
    stopLoopHandle();

    conManager.unregisterNetworkCallback(networkCallback);

}

private void readAdvanceParameter(){

    singleModule = new SingleControlWiFiModule(wifiNetwork, singleResult);
    singleModule.startTask(ipConnect, new String[]{Constant.ADVANCE_DATA});
}

private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback(){
    @Override
    public void onAvailable(Network network) {
        super.onAvailable(network);

        Log.w(TAG, "Network available: "+network);
        //Set Network
        wifiNetwork = network;
        //Create Handler for loop reading
        handler = new Handler();
        //Start reading
        readAdvanceParameter();
    }

    [@Override
    public void onLost(Network network)][1] {
        super.onLost(network);

        Log.w(TAG, "Network loss: "+network);
        statusText.setText(R.string.no_network);
        statusText.setVisibility(View.VISIBLE);
        //Stop loop
        stopLoopHandle();
    }

};

private SingleControlWiFiModule.OnSingleResult singleResult = new SingleControlWiFiModule.OnSingleResult() {
    @Override
    public void onFinish(Task task) {
        Log.w(TAG, "Read parameter finish :: Value: "+ Arrays.toString(task.response));
        //Check result
        if (task.response.length>=UNIT_2016_2034.length){
            //Close Status
            statusText.setVisibility(View.INVISIBLE);
            //Set item
            items.clear(); String d, t, f; int offset = 2016;
            for (int i=0; i<UNIT_2016_2034.length; i++){
                f = desFunction[i];
                d = task.response[i];
                if (i>0 && i<5){
                    d = String.valueOf(ControlActivity.getActualIndoorTemp(getIntegerOf(d)));
                }else if (i==11 | (i>12 && i<15)){
                    d = onePoint.format(getIntegerOf(d)/10);
                }else if (i==12){
                    d = twoPoint.format(getIntegerOf(d)/100);
                }else if (i==10){
                    t = Integer.toHexString(getIntegerOf(d));
                    Log.w(TAG, "In: "+d+" Hex: "+t);
                    d = getErrorDetail(t);
                    f = f + " ["+t+"]";
                }
                Parameter p = new Parameter(offset+i, f, d, UNIT_2016_2034[i]);
                items.add(p);
            }
            //Update adapter
            adapter.notifyDataSetChanged();
            //Visible item
            if (itemView.getVisibility()==View.INVISIBLE){
                itemView.setVisibility(View.VISIBLE);
                loadProgress.setVisibility(View.INVISIBLE);
            }
        }else {
            //Failed reading
            Log.e(TAG, "Read parameter Failed: "+task.response[0]);
            statusText.setText(task.response[0]);
            statusText.setVisibility(View.VISIBLE);

            //Stop loop
            if (task.response[0].equals(SingleControlWiFiModule.ERR_OTHER)){
                singleModule.cancel(true);
                stopLoopHandle();
            }

        }

        //Call loop reading handle
        if (handler!=null){
            handler.removeCallbacks(loopRun);
            handler.postDelayed(loopRun, INTERVAL);
        }
    }
};

在测试中,我将服务器设置为响应客户端发送的相同消息。

02-24 15:54:26.478 23501-23596/com.apyeng.tasakicentral W/SingleControl: 
Send request success :: [12]
02-24 15:54:27.275 23501-23581/com.apyeng.tasakicentral W/Advance: Network loss: 197
02-24 15:54:27.375 23501-23581/? I/Process: Sending signal. PID: 23501 SIG: 9

如何解决这个问题?

0 个答案:

没有答案