2015-02-23 4 views
-1

Недавно я начал работать над домашней системой мониторинга. Я использую и arduino для чтения данных датчика (например, температуры) и отправлю его на малиновый pi через последовательный порт. На малине pi я запускаю Java-сервер TCP, который считывает последовательные данные и отправляет их клиентам (формат: температура: свет). Все это работает отлично, поэтому вчера я начал разработку Android-приложения, которое подключается к серверу и отображает данные. Эта часть также работает очень хорошо. Но я столкнулся с проблемой, когда пытался создать виджет. Поскольку мне нужно обновлять TextView каждые 1 сек (или всякий раз, когда данные получены), я храню RemoteViews, AppWidgetManager и int [] appWidgetIds в некоторых частных переменных, которые обновляются каждый раз, когда вызывается метод onUpdate(). Проблема в том, что переменные имеют значение, но когда я пытаюсь использовать их iside нового потока, созданного методом 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(); 
    } 
} 
} 

Я довольно новый для андроид и этот кусок кода только для проверки связи и начать обучение немного больше о андроиде. Я собираюсь перестроить все приложение и сделать код намного приятнее после того, как я получу эту работу.

Спасибо за помощь :)

Я перепробовал все виды материала уже, как синхронизированные блоки и летучий модификатор ... Ничто не кажется, работает ...

+0

Почему у вас есть три синхронизированных блока в каскаде? – Blackbelt

+0

@Blackbelt Потому что мне нужно разделить все три объекта. Когда я показываю их значения в методе onUpdate, значения не равны нулю. Но значения, отображаемые в потоке, равны нулю. Если это имеет какое-то значение. :) –

ответ

1

ли работает материал на пользовательском интерфейсе нить поможет вам.

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 

        } 
       }); 
+0

Не жалко, я пробовал это уже, но похоже, что этот метод недоступен в виджетах. –

+0

может у вас попробуй еще раз .. обновленный ответ –

+0

Эй, это работает :) Чем ты! Я просто хочу знать, есть ли простой способ остановить поток после отправки его обработчику? –

Смежные вопросы