如何从 运行() 方法访问变量?
How can I access the variable from run() method?
我是线程概念的新手。我在 android 做套接字编程。我想以各种方式使用从客户端收到的消息。但是我无法从 Runnable 接口的 运行() 方法访问消息。下面是我的代码
'''
class Thread1 implements Runnable {
@Override
public void run() {
Socket socket;
while (true) {
try {
serverSocket = new ServerSocket(SERVER_PORT);
socket = serverSocket.accept();
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = input.readLine();
if (message != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvMessages.setText("" + message + "\n");
}
});
} else {
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
'''
这里我想在不同的class或方法中使用消息变量。
您可以在 activity 中简单地创建一个处理程序对象,例如 Handler activtyHandler = new Handler()
接下来将此处理程序传递给您正在创建的线程对象,然后 post 您想要的任何代码 运行 关于 activity 如下
mHandler.post(new Runnable() {
@Override
public void run() {
tvMessages.setText("" + message + "\n");
}
});
对于您的特定代码,将消息变量设为 final:
final String message = input.readLine();
附带说明一下,tvMessages 来自哪里?明明是一个TextView,但是它是怎么到达class实现的呢?您应该将 tvMessages 更改为 WeakReference 而不是强引用,因为在您的代码中使用它可能会产生 Activity 上下文泄漏。
此外,虽然问题中没有问到,但与其在每次收到消息时都创建一个新的可运行对象,不如在创建工作线程之前创建一个绑定到主线程的 Handler 会更有效,然后用它来发送消息到 UI。这将避免很多不必要的可运行实例。
不是 100% 确定问题出在哪里,但也许您缺少 final
关键字?例如以下工作。
final String message = "hello";
runOnUiThread(new Runnable() {
@Override
public void run() {
System.out.println("" + message + "\n");
}
});
如果没有 final 你应该得到以下错误:
Cannot refer to the non-final local variable message defined in an
enclosing scope
您还可以使用以下字段创建 类:
static class MyRunnable implements Runnable {
private final String message;
public MyRunnable(String message) {
this.message = message;
}
@Override
public void run() {
System.out.println("" + message + "\n");
}
}
那么你会像这样使用它:
final String message = "hello";
runOnUiThread(new MyRunnable(message));
我是线程概念的新手。我在 android 做套接字编程。我想以各种方式使用从客户端收到的消息。但是我无法从 Runnable 接口的 运行() 方法访问消息。下面是我的代码
'''
class Thread1 implements Runnable {
@Override
public void run() {
Socket socket;
while (true) {
try {
serverSocket = new ServerSocket(SERVER_PORT);
socket = serverSocket.accept();
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = input.readLine();
if (message != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tvMessages.setText("" + message + "\n");
}
});
} else {
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
'''
这里我想在不同的class或方法中使用消息变量。
您可以在 activity 中简单地创建一个处理程序对象,例如 Handler activtyHandler = new Handler()
接下来将此处理程序传递给您正在创建的线程对象,然后 post 您想要的任何代码 运行 关于 activity 如下
mHandler.post(new Runnable() {
@Override
public void run() {
tvMessages.setText("" + message + "\n");
}
});
对于您的特定代码,将消息变量设为 final:
final String message = input.readLine();
附带说明一下,tvMessages 来自哪里?明明是一个TextView,但是它是怎么到达class实现的呢?您应该将 tvMessages 更改为 WeakReference 而不是强引用,因为在您的代码中使用它可能会产生 Activity 上下文泄漏。
此外,虽然问题中没有问到,但与其在每次收到消息时都创建一个新的可运行对象,不如在创建工作线程之前创建一个绑定到主线程的 Handler 会更有效,然后用它来发送消息到 UI。这将避免很多不必要的可运行实例。
不是 100% 确定问题出在哪里,但也许您缺少 final
关键字?例如以下工作。
final String message = "hello";
runOnUiThread(new Runnable() {
@Override
public void run() {
System.out.println("" + message + "\n");
}
});
如果没有 final 你应该得到以下错误:
Cannot refer to the non-final local variable message defined in an
enclosing scope
您还可以使用以下字段创建 类:
static class MyRunnable implements Runnable {
private final String message;
public MyRunnable(String message) {
this.message = message;
}
@Override
public void run() {
System.out.println("" + message + "\n");
}
}
那么你会像这样使用它:
final String message = "hello";
runOnUiThread(new MyRunnable(message));