如何在线程之间共享对象

时间:2015-02-23 13:31:21

标签: android multithreading object shared

最近我开始研究家庭监控系统。我使用和arduino读取传感器数据(如温度)并通过串口将其发送到树莓派。在树莓派上,我运行了一个java TCP服务器,它读取串行数据并将其发送给客户端(格式:温度:光)。这一切都很好,所以昨天我开始开发一个连接到服务器并显示数据的Android应用程序。这部分也很好用。但是当我试图创建一个小部件时,我遇到了一个问题。因为我需要每1秒(或者每当收到数据时)更新TextViews,我将RemoteViews,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的知识。我将重建整个应用程序,并在我开始工作后使代码更好。

感谢您的帮助:)

我已经尝试了各种各样的东西,比如synchronized块和volatile修饰符...似乎没有什么工作......

1 个答案:

答案 0 :(得分:1)

在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

                    }
                });