Android 之AsyncTask&UDP

2017-08-11  本文已影响0人  天涯笑笑生

AsyncTask 和 UDP 相结合,实现在Activity实时更新数据。

UdpReceiveTask.java

package com.example.jony.hcsdemo1.hcs.udp;

import android.os.AsyncTask;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by jony on 17/8/11.
 */

public class UdpReceiveTask extends AsyncTask<DatagramSocket, String, Integer> {

    public interface IReciviceListener {

        void receiveInstruction(String instruction);
    }


        private static final String TAG = "UdpReceiveTask";
    private static final boolean isReceive = true;

    //存储接收到的数据
    private static byte[] recvBuf = new byte[1024];
    private static DatagramPacket packet = null;

//    private static  IReciviceListener listener;
//    public static void setListener(IReciviceListener listener) {
//        UdpReceiveTask.listener = listener;
//    }

    //用map存储大量监听者
    private static HashMap<String, IReciviceListener>  listenerMap= new HashMap<String, IReciviceListener>();

    public static void setListener(String key, IReciviceListener listener) {
        listenerMap.put(key,listener);
    }

    @Override
    protected void onPreExecute() {
//        super.onPreExecute();

        //创建packet
        packet = new DatagramPacket(recvBuf, recvBuf.length);

    }

    @Override
    protected Integer doInBackground(DatagramSocket... datagramSockets) {

        if (datagramSockets[0] != null){
            //清理下字节数组
//            DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
            if (packet != null){

                while (isReceive){
                    try {
                        datagramSockets[0].receive(packet);

                        //处理接收到的数据
                        String recvStr = new String(recvBuf, 0, packet.getLength());
//                        Log.d(TAG, "run: receive:"+recvStr);
                        publishProgress(recvStr);


                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }else {
                Log.e(TAG, "doInBackground: packet is null");
            }


        }else {
            Log.e(TAG, "doInBackground: datagramSocke is null");
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
//        super.onProgressUpdate(values);

        Log.d(TAG, "onProgressUpdate: "+values[0]);
//        if (listener != null){
//            listener.receiveInstruction(values[0]);
//        }

        //map test
        Iterator iter = listenerMap.entrySet().iterator();
        while (iter.hasNext()){
            Map.Entry<String, IReciviceListener> entry = (Map.Entry<String, IReciviceListener>) iter.next();

            if (entry.getKey().equals(values[0])) {
                entry.getValue().receiveInstruction(values[0]);
            }
        }

    }

    @Override
    protected void onPostExecute(Integer integer) {
        super.onPostExecute(integer);
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }
}

MainActivity.java

package com.example.jony.hcsdemo1;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.example.jony.hcsdemo1.hcs.NetworkService;
import com.example.jony.hcsdemo1.hcs.udp.UdpReceiveTask;

public class MainActivity extends AppCompatActivity implements UdpReceiveTask.IReciviceListener{

    private TextView tv_text;
    private Button btn_open2;


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

        tv_text = (TextView) findViewById(R.id.tv_text);
        btn_open2 = (Button) findViewById(R.id.btn_open2);
        btn_open2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent open2Intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(open2Intent);
            }
        });

//        UdpReceiveTask.listener = this;
        UdpReceiveTask.setListener("1", this);

        //启动服务
        Intent startIntent = new Intent(this, NetworkService.class);
        startService(startIntent);
    }


    @Override
    public void receiveInstruction(String instruction) {
        tv_text.setText(instruction);
    }

}

NetworkService.java

public class NetworkService extends Service {

    private static final String TAG = "NetworkService";
    private static final int LOCAL_PORT = 5000;
    private DatagramSocket socket = null;


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    /**
     * 服务创建时调用
     */
    @Override
    public void onCreate() {
        super.onCreate();

        //创建socket
        try {
            socket = new DatagramSocket(LOCAL_PORT);
        } catch (SocketException e) {

            Log.e(TAG, "onCreate: socket create failed!");
            e.printStackTrace();

        }

    }

    /**
     * 每次服务启动时调用
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (socket != null){
            new UdpReceiveTask().execute(socket);
        }else {
            Log.e(TAG, "onStartCommand: socket is null");
        }


        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 服务销毁时调用
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

注1:IReciviceListener用来回调的接口可以单独在外面,不过写在里面感觉挺爽的。
注2:用HashMap存储实现接口的类,可以精准的回调。
注3:服务创建时,task服务随之启动运行,当然socket和AsyncTask在服务销毁时,应当随之销毁
注4:NetworkService服务应当在application中启动管理,也可以通过NetworkService管理UdpReceiveTask

上一篇下一篇

猜你喜欢

热点阅读