android sulotion用于处理接收数据上的套接字

时间:2017-01-06 15:45:44

标签: android multithreading sockets tcp connection

我创建了一个处理TCP Socket的应用程序,但我陷入了处理从服务器接收的数据,它在单独的线程中处理了不允许我从其他Activity访问Context的句柄或其他不会发生在它的线程上的东西,我也希望在其他地方使用此Socket,如通知活动,聊天活动

我愿意接受你的提示和建议方式

这就是我写的

import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Random;

public class ApplicationLoader extends Application
{
    private static volatile Handler _Handler;
    private volatile Context _Context;
    private Client _Client;

    @Override
    public void onCreate()
    {
        super.onCreate();

        _Context = getApplicationContext();
        _Handler = new Handler(_Context.getMainLooper());
        _Client = new Client();
    }

    public Context GetContext()
    {
        return _Context;
    }

    public Handler GetHandler()
    {
        return _Handler;
    }

    public Client GetClient()
    {
        return _Client;
    }

    public void TEST(String ee)
    {
        Toast.makeText(GetContext(), ee, Toast.LENGTH_SHORT).show();
    }

    private class Client
    {
        private SocketReceive _SocketReceive = new SocketReceive()
        {
            @Override
            public void OnReceive(String Message)
            {
                TEST(Message); // RETURN : Can't create handler inside thread that has not called Looper.prepare()
            }
        };

        private boolean IsConnected = false;
        private PrintWriter _Writer;
        private Thread _Receiver;
        private Socket _Socket;

        Client()
        {
            try
            {
                if (_Receiver != null)
                {
                    _Receiver.interrupt();
                    _Receiver = null;
                }

                if (_Socket != null)
                {
                    _Socket.close();
                    _Socket = null;
                }

                if (_Writer != null)
                {
                    _Writer.close();
                    _Writer = null;
                }
            }
            catch (Exception e)
            {
                e.getStackTrace();
            }

            IsConnected = false;

            new Thread(new Connection()).start();
        }

        private void SendMessage(String Message)
        {
            if (IsConnected && _Writer != null)
            {
                _Writer.write(Message);
                _Writer.flush();
            }
        }

        private class Connection implements Runnable
        {
            public void run()
            {
                try
                {
                    while (true)
                    {
                        try
                        {
                            if (!IsConnected)
                            {
                                InetAddress HostAddress = InetAddress.getByName(GetRandomServer());
                                _Socket = new Socket(HostAddress, 9080);
                                _Socket.setKeepAlive(true);
                                _Socket.setTcpNoDelay(true);

                                _Writer = new PrintWriter(_Socket.getOutputStream());

                                _Receiver = new Thread(new Receiver());
                                _Receiver.start();

                                IsConnected = true;
                            }
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                            IsConnected = false;
                        }

                        try
                        {
                            Thread.sleep(8000);
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }

        private class Receiver implements Runnable
        {
            public void run()
            {
                try
                {
                    if (IsConnected)
                    {
                        int BufferRead;
                        char[] Buffer = new char[2048];
                        BufferedReader BufferReader = new BufferedReader(new InputStreamReader(_Socket.getInputStream()));

                        while ((BufferRead = BufferReader.read(Buffer)) != -1)
                        {
                             if (_SocketReceive != null)
                                _SocketReceive.OnReceive(new String(Buffer).substring(0, BufferRead));
                        }
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
        }

        private String GetRandomServer()
        {
            Random random = new Random();

            switch (random.nextInt(5) + 1)
            {
                case 1:  return "10.201.58.119";
                case 2:  return "10.201.58.119";
                case 3:  return "10.201.58.119";
                case 4:  return "10.201.58.119";
                case 5:  return "10.201.58.119";
                default: return "10.201.58.119";
            }
        }
    }

    interface SocketReceive
    {
        void OnReceive(String Message);
    }
}

1 个答案:

答案 0 :(得分:1)

不会撒谎,你的代码很难解释,但我想我明白了吗?

无论如何,要将数据从一个线程推送到另一个线程,有很多不同的方法可以帮助您实现目标。最简单的方法之一是打包数据并将其发送到目标线程以进行进一步处理。那里有很多例子。

当您的套接字正在创建/连接/接收数据时,将包含处理程序的对象或类传递给接收数据的类,并构建消息和包以便于从可运行线程发布到ui线程。 / p>

主线程将关闭此内容:

@Override
public void handleMessage(Message message){
    Bundle bundle = message.getData();
    //do something with bundle
}

当你的runnable线程在需要将数据移动到另一个线程时会调用这些:

message = mainThread.obtainMessage();
message.what = valINT;
message.setData(bundle);
mainthread.sendMessage(message);

希望这有帮助!