如何在线程之间共享一个对象
How to share an object between threads
最近我开始研究家庭监控系统。我正在使用和 arduino 读取传感器数据(如温度)并通过串行端口将其发送到 raspberry pi。在 raspberry pi 上,我是 运行 一个 java TCP 服务器,它读取串行数据并将其发送到客户端(格式:temperature:light)。这一切都工作得很好,所以昨天我开始开发一个连接到服务器并显示数据的 android 应用程序。这部分也很好用。但是当我试图制作一个小部件时,我 运行 遇到了问题。因为我需要每 1 秒(或每当收到数据)更新一次 TextView,所以我将 RemoteView、AppWidgetManager 和 int[] appWidgetIds 存储在一些私有变量中,这些变量在每次调用 onUpdate() 方法时都会刷新。问题是变量有一个值,但是当我尝试在 startListener() 方法创建的新线程旁边使用它们时,我得到一个 NullPointerException。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.util.Log;
import android.widget.RemoteViews;
public class WidgetActivity extends AppWidgetProvider {
private volatile RemoteViews views;
private volatile AppWidgetManager manager;
private volatile int[] ids;
private volatile Thread listener;
private volatile boolean running = false;
private volatile Socket s;
private volatile BufferedReader br;
public void onEnabled(Context context){
startListener();
}
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
views = new RemoteViews(context.getPackageName(), R.layout.activity_widget);
Log.d("Views1", views.toString());
manager = appWidgetManager;
Log.d("Manager1", manager.toString());
ids = appWidgetIds;
Log.d("IDS1", ids.toString());
startListener();
}
public void onDisabled(Context context){
running = false;
if(listener != null){
listener.interrupt();
}
listener = null;
try {
if(br != null){
br.close();
}
if(s != null){
s.close();
}
} catch (IOException e) {
}
}
public void startListener(){
if(listener == null || !listener.isAlive() || !running){
listener = new Thread(){
public void run(){
synchronized(views){
synchronized(ids){
synchronized(manager){
try {
s = new Socket("000.000.000.000", 7777);
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
running = true;
while(running && !this.isInterrupted()){
String data = br.readLine();
if(data != null && data.contains(":")){
String[] split = data.split(":");
if(views != null){
views.setTextViewText(R.id.tempWidget, "Temperature: " + split[0]);
views.setTextViewText(R.id.lightWidget, "Light: " + split[1]);
}else{
Log.d("Views", "NULL!");
}
if(ids != null && manager != null){
for(int id : ids){
manager.updateAppWidget(id, views);
}
}else{
Log.d("IDS", "NULL!");
Log.d("Manager", "NULL!");
}
}
}
if(br != null){
br.close();
}
if(s != null){
s.close();
}
listener = null;
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
}
}
}
};
listener.start();
}
}
}
我是 android 的新手,这段代码只是为了测试通信并开始更多地了解 android。我将重建整个应用程序并在我开始工作后使代码更好。
感谢您的帮助:)
我已经尝试了各种东西,比如同步块和 volatile 修饰符……似乎没有任何效果……
运行 UI 话题中的内容对您有帮助吗..
public void startListener(){
if(listener == null || !listener.isAlive() || !running){
listener = new Thread(){
public void run(){
Handler mHandler = new Handler();
mHandler.post(new Runnable(){
public void run() {
//try here
}
});
最近我开始研究家庭监控系统。我正在使用和 arduino 读取传感器数据(如温度)并通过串行端口将其发送到 raspberry pi。在 raspberry pi 上,我是 运行 一个 java TCP 服务器,它读取串行数据并将其发送到客户端(格式:temperature:light)。这一切都工作得很好,所以昨天我开始开发一个连接到服务器并显示数据的 android 应用程序。这部分也很好用。但是当我试图制作一个小部件时,我 运行 遇到了问题。因为我需要每 1 秒(或每当收到数据)更新一次 TextView,所以我将 RemoteView、AppWidgetManager 和 int[] appWidgetIds 存储在一些私有变量中,这些变量在每次调用 onUpdate() 方法时都会刷新。问题是变量有一个值,但是当我尝试在 startListener() 方法创建的新线程旁边使用它们时,我得到一个 NullPointerException。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.util.Log;
import android.widget.RemoteViews;
public class WidgetActivity extends AppWidgetProvider {
private volatile RemoteViews views;
private volatile AppWidgetManager manager;
private volatile int[] ids;
private volatile Thread listener;
private volatile boolean running = false;
private volatile Socket s;
private volatile BufferedReader br;
public void onEnabled(Context context){
startListener();
}
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
views = new RemoteViews(context.getPackageName(), R.layout.activity_widget);
Log.d("Views1", views.toString());
manager = appWidgetManager;
Log.d("Manager1", manager.toString());
ids = appWidgetIds;
Log.d("IDS1", ids.toString());
startListener();
}
public void onDisabled(Context context){
running = false;
if(listener != null){
listener.interrupt();
}
listener = null;
try {
if(br != null){
br.close();
}
if(s != null){
s.close();
}
} catch (IOException e) {
}
}
public void startListener(){
if(listener == null || !listener.isAlive() || !running){
listener = new Thread(){
public void run(){
synchronized(views){
synchronized(ids){
synchronized(manager){
try {
s = new Socket("000.000.000.000", 7777);
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
running = true;
while(running && !this.isInterrupted()){
String data = br.readLine();
if(data != null && data.contains(":")){
String[] split = data.split(":");
if(views != null){
views.setTextViewText(R.id.tempWidget, "Temperature: " + split[0]);
views.setTextViewText(R.id.lightWidget, "Light: " + split[1]);
}else{
Log.d("Views", "NULL!");
}
if(ids != null && manager != null){
for(int id : ids){
manager.updateAppWidget(id, views);
}
}else{
Log.d("IDS", "NULL!");
Log.d("Manager", "NULL!");
}
}
}
if(br != null){
br.close();
}
if(s != null){
s.close();
}
listener = null;
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
}
}
}
};
listener.start();
}
}
}
我是 android 的新手,这段代码只是为了测试通信并开始更多地了解 android。我将重建整个应用程序并在我开始工作后使代码更好。
感谢您的帮助:)
我已经尝试了各种东西,比如同步块和 volatile 修饰符……似乎没有任何效果……
运行 UI 话题中的内容对您有帮助吗..
public void startListener(){
if(listener == null || !listener.isAlive() || !running){
listener = new Thread(){
public void run(){
Handler mHandler = new Handler();
mHandler.post(new Runnable(){
public void run() {
//try here
}
});