在AsyncTask中使用Handler

时间:2016-05-26 19:03:39

标签: android multithreading tcp android-asynctask handler

我正在开发一个使用Wifi / Tcp连接与机器人通信的应用程序。目前我正在使用单个线程来管理tcp连接,使用TcpClient类和我的MainActivity中的“ConnectTask extends AsyncTask”。

到目前为止,这就是我所拥有的:

TcpClient.java

private OnMessageReceived mMessageListener = null;

private int bufferSize = 5000;
public ByteBuffer bf;
private BufferedInputStream inFromServer;
private BufferedOutputStream outFromClient;
.
.
.
public void run() {

    mRun = true;
    try {
        //here you must put your computer's IP address.
        InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

        Log.e("TCP Client", "C: Connecting...");

        //create a socket to make the connection with the server
        Socket socket = new Socket(serverAddr, SERVER_PORT);

        try {
            Log.i("Debug", "inside try catch");

            //receives the message which the server sends back

            inFromServer = new BufferedInputStream(socket.getInputStream());
            outFromClient = new BufferedOutputStream(socket.getOutputStream());


            bf = ByteBuffer.allocate(bufferSize);




            while (mRun) {
               // Log.i("Debug", "inside while mRun");

                bf.order(ByteOrder.LITTLE_ENDIAN);
                for (int i=0;i<5000;i++) {
                    int b = inFromServer.read();

                    if (b == -1) {
                        break;
                    }

                    bf.put((byte) b);

                }

                if ( bf != null && mMessageListener != null) {
                    //call the method messageReceived from MyActivity class
                   // Log.i("Debug","Message received !");
                    mMessageListener.messageReceived(bf);
                    mMessageListener.updateBatteryLvl();
                }
                bf.position(0);
            }
        }
.
.
.

这是我在MainActivity中的ConnectTask:

public class ConnectTask extends AsyncTask<Void, ByteBuffer, TcpClient> {

    @Override
    protected TcpClient doInBackground(Void... params) {
        //we create a TCPClient object and
        mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
            @Override
            //here the messageReceived method is implemented
            public void messageReceived(ByteBuffer message) throws IOException {
                //this method calls the onProgressUpdate
                byte[] resultat = new byte[4000];
                resultat = message.array();
                updateBatteryLvl();
                message.clear();

我没有在tcpclient或connecttask中使用任何处理程序,但我看到一些教程使用它们进行Tcp连接,我想知道他们为什么要使用它?我已经测试了与机器人的连接,我收到它发送的数据非常好。 如果你有多线程写在同一个文件中,那么处理程序是否像信号量一样使用?

2 个答案:

答案 0 :(得分:0)

  

如果您有多线程写入,那么处理程序是否像信号量一样使用   例如同一个文件?

或多或少,是的。 处理程序只能在带有Looper的线程中创建(调用其构造函数)(主线程是带有looper的线程)。

然后,您可以通过处理程序发布Runnables和Messages以便运行(将来的某个时间)。这些可运行/消息由hanlder排队,并被分派以在它们被创建的线程上运行。所以基本上,如果你在不同的线程中运行东西,并且想要在不担心竞争条件的情况下执行某些操作(或者需要在特定线程上运行这些操作,比如当你需要更新UI时),你可以发布&# 34;操作&#34;在处理程序中,这就是全部。

在您的情况下,使用AsyncTask,它会执行相同的操作,在分离的线程中执行工作,并将结果提交给MAIN THREAD。如果您需要管理不同的线程,并将结果提交到单个而不是MAIN THREAD,则您需要使用处理程序。 但是当你描述你正在做的事情时,就没有必要了。

答案 1 :(得分:0)

您无法在UI线程(主线程)中执行长时间运行操作,或者您将获得"application not responding"(ANR)。 所以你必须使用多线程和Android框架提供基础设施,以便更容易与主线程进行数据同步(Android UI工具包不是线程安全的)。

您的选择可能会导致问题,因为:

  • AsyncTask只能用于需要几秒钟的操作。

  • AsyncTasks在单个后台线程(来自API 11)上串行执行。因此,长时间跑步的工人可以阻止其他人。

  • AsyncTasks不尊重主机Activity的生命周期(可能会导致内存泄漏)。

  • 查杀清单中的优先级为low