【问题标题】:android sulotion for handling socket on receive data [closed]用于在接收数据时处理套接字的 android sulition [关闭]
【发布时间】:2017-05-21 10:03:16
【问题描述】:

我已经创建了一个处理 TCP Socket 的应用程序,但是我停留在从服务器接收的处理数据中,它在单独的线程中处理,这不允许我从其他 Activity 访问 Context 或其他不会发生的事情线程,我也想在其他地方使用这个套接字,比如通知活动、聊天活动

我愿意接受您的提示和建议

这是我写的

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);
    }
}

【问题讨论】:

    标签: android multithreading sockets tcp connection


    【解决方案1】:

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

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

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

    主线程将有这个或类似的东西:

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

    当需要将数据移动到另一个线程时,您的可运行线程会调用这些:

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

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2023-02-05
      • 2011-05-22
      • 1970-01-01
      • 2023-03-20
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      相关资源
      最近更新 更多