最近我開始研究家庭監控系統。我正在使用和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修飾符......似乎沒有任何工作...
爲什麼你有三個同步塊在級聯? – Blackbelt 2015-02-23 13:34:19
@Blackbelt因爲我需要共享所有三個對象。當我在onUpdate方法中顯示它們的值時,值不爲null。但是線程中顯示的值爲空。如果這使得任何意見。 :) – 2015-02-23 13:55:56