如何在Android中通过Handler传递消息?

时间:2022-08-20 23:57:54

I'm learning how work handler in Android. I did Android server and socket class. I want send some message (i.e. "New Connect") from socket to mainactivity, when somebody connect to server. I can't figure out how to pass from socket to mainactivity. (More in comments)

我正在学习Android中的工作处理程序。我做了Android服务器和套接字类。当有人连接到服务器时,我想从套接字向mainactivity发送一些消息(即“New Connect”)。我无法弄清楚如何从套接字传递到mainactivity。 (更多评论)

HttpServerActivity.java

public class HttpServerActivity extends Activity implements OnClickListener{

private SocketServer s;
private static final int READ_EXTERNAL_STORAGE = 1;

Button btn1, btn2;

// There I'm trying to send message to button, when somebody connected
Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        super.handleMessage(msg);
        String text = (String)msg.obj;
        btn1.setText(text);
    }
};

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

    Button btn1 = (Button)findViewById(R.id.button1);
    Button btn2 = (Button)findViewById(R.id.button2);

    btn1.setOnClickListener(this);
    btn2.setOnClickListener(this);

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.http_server, menu);
    return true;
}


@Override
public void onClick(View v) {

    if (v.getId() == R.id.button1) {

        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);

        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE);
        } else {
            // I dont know figure out in this place 
            s = new SocketServer(h);
            s.start();
        }
    }
    if (v.getId() == R.id.button2) {
        s.close();
        try {
            s.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {

        case READ_EXTERNAL_STORAGE:
            if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // I dont know figure out in this place 
                s = new SocketServer(h);
                s.start();
            }
            break;

        default:
            break;
    }
}
}

SocketServer.java

public class SocketServer extends Thread {

private final Handler mHandler;
public SocketServer(Handler handler)
{
    mHandler = handler;
}
ServerSocket serverSocket;
public final int port = 12345;
boolean bRunning;
public void close() {
    try {
        serverSocket.close();
    } catch (IOException e) {
        Log.d("SERVER", "Error, probably interrupted in accept(), see log");
        e.printStackTrace();
    }
    bRunning = false;
}

public Handler mHandler;
public void run() {
    try {
        Log.d("SERVER", "Creating Socket");
        serverSocket = new ServerSocket(port);
        bRunning = true;
        while (bRunning) {
            Log.d("SERVER", "Socket Waiting for connection");
            Socket s = serverSocket.accept();
            Log.d("SERVER", "Socket Accepted");

            // trying to send some message
            String[] messageString = new String[1];

            Message message = Message.obtain();
            messageString[0]="OK";
            message.obj = messageString;

            mHandler.sendMessage(message);

            OutputStream o = s.getOutputStream();
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(o));

            out.write("HTTP/1.0 200 OK\n" +
                    "Date: Fri, 31 Dec 1999 23:59:59 GMT\n" +
                    "Content-Type: text/html\n" +
                    "Content-Length: 1354\n" +
                    "\n" +
                    "<html>\n" +
                    "<body>\n" +
                    "<h1> Connected </h1>\n" +
                    "</body>\n" +
                    "</html>");
            out.flush();


            while (!((tmp = in.readLine()).isEmpty()))
            {
                Log.d("Header", tmp);
                if (tmp.startsWith("GET"))
                {
                    getRequest = tmp;
                }
            }

            s.close();
            Log.d("SERVER", "Socket Closed");

        }
    }
    catch (IOException e) {
        if (serverSocket != null && serverSocket.isClosed())
            Log.d("SERVER", "Normal exit");
        else {
            Log.d("SERVER", "Error");
            e.printStackTrace();
        }
    }
    finally {
        serverSocket = null;
        bRunning = false;
    }
}

}

2 个解决方案

#1


1  

This is a sample of a bigger project I was involved a few years ago. You will not be able to run as it is, but I think you can see how the communication between a Service and an Activity works. Feel free to ask if anything is not clear

这是几年前我参与的一个更大项目的样本。您将无法按原样运行,但我认为您可以看到服务和活动之间的通信是如何工作的。如果有什么不清楚,请随时询问

Service

public class BluetoothService {

   private final Handler mHandler;

    public BluetoothService(Context context, Handler handler) {

         mHandler = handler;
    }

    public synchronized void Connecting(...) {

      ...

      Message MenssageToActivity = mHandler.obtainMessage(Cliente_Bluetooth.MESSAGE_HELLO);
      Bundle bundle = new Bundle();
      bundle.putString(BluetoothClient.DEVICE_NAME, " Gorkatan");
      MensajeParaActivity.setData(bundle);
      mHandler.sendMessage(MensajeParaActivity);

      ...

    }
}

Activity

public class BluetoothClient{

      public static final int MESSAGE_HELLO = 1;
      public static final int MESSAGE_BYE = 2;

      @Override
      protected void onCreate(Bundle savedInstanceState) {

            mBluetoothService = new BluetoothService(this, mHandler);
      }

      private final Handler mHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {


                case MESSAGE_HELLO:

                    String mName = null; 
                    mName = msg.getData().getString(DEVICE_NAME);

                    Toast.makeText(getApplicationContext(), "Hello "+ mName, Toast.LENGTH_SHORT).show();

                break; 

                case MESSAGE_BYE:

                    System.out.println("Bye!")

                break;


}

Here it is the whole project (which has got comments and variable names in Spanish):

这是整个项目(其中有西班牙语的注释和变量名称):

https://github.com/ignacio-alorre/PDF-Dispenser/tree/master/Client/Cliente_Bluetooth/src/com/cliente_bluetooth

#2


0  

If you plan on sending data from a thread to your handler then use obtainMessage to create a message object.

如果您计划将数据从线程发送到处理程序,则使用obtainMessage创建消息对象。

You must also use the same instance of the handler to handleMessage and sendMessage.

您还必须使用相同的处理程序实例来处理handleMessage和sendMessage。


Here you will find a great resource explaining how to use Handler:

在这里,您将找到一个很好的资源,解释如何使用Handler:

https://www.youtube.com/watch?v=LJ_pUlWzGsc

#1


1  

This is a sample of a bigger project I was involved a few years ago. You will not be able to run as it is, but I think you can see how the communication between a Service and an Activity works. Feel free to ask if anything is not clear

这是几年前我参与的一个更大项目的样本。您将无法按原样运行,但我认为您可以看到服务和活动之间的通信是如何工作的。如果有什么不清楚,请随时询问

Service

public class BluetoothService {

   private final Handler mHandler;

    public BluetoothService(Context context, Handler handler) {

         mHandler = handler;
    }

    public synchronized void Connecting(...) {

      ...

      Message MenssageToActivity = mHandler.obtainMessage(Cliente_Bluetooth.MESSAGE_HELLO);
      Bundle bundle = new Bundle();
      bundle.putString(BluetoothClient.DEVICE_NAME, " Gorkatan");
      MensajeParaActivity.setData(bundle);
      mHandler.sendMessage(MensajeParaActivity);

      ...

    }
}

Activity

public class BluetoothClient{

      public static final int MESSAGE_HELLO = 1;
      public static final int MESSAGE_BYE = 2;

      @Override
      protected void onCreate(Bundle savedInstanceState) {

            mBluetoothService = new BluetoothService(this, mHandler);
      }

      private final Handler mHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {


                case MESSAGE_HELLO:

                    String mName = null; 
                    mName = msg.getData().getString(DEVICE_NAME);

                    Toast.makeText(getApplicationContext(), "Hello "+ mName, Toast.LENGTH_SHORT).show();

                break; 

                case MESSAGE_BYE:

                    System.out.println("Bye!")

                break;


}

Here it is the whole project (which has got comments and variable names in Spanish):

这是整个项目(其中有西班牙语的注释和变量名称):

https://github.com/ignacio-alorre/PDF-Dispenser/tree/master/Client/Cliente_Bluetooth/src/com/cliente_bluetooth

#2


0  

If you plan on sending data from a thread to your handler then use obtainMessage to create a message object.

如果您计划将数据从线程发送到处理程序,则使用obtainMessage创建消息对象。

You must also use the same instance of the handler to handleMessage and sendMessage.

您还必须使用相同的处理程序实例来处理handleMessage和sendMessage。


Here you will find a great resource explaining how to use Handler:

在这里,您将找到一个很好的资源,解释如何使用Handler:

https://www.youtube.com/watch?v=LJ_pUlWzGsc