2016-01-27 4 views
2

Я работаю над Android-приложением, которое ведет себя странно. Одна из первых вещей, которую это приложение делает при запуске, - начать прослушивающий поток, который слушает приложение «сервер» на том же устройстве, чтобы получить данные. Как только эти данные будут получены потоком прослушивания, я использую его для обновления основного вида. Это, однако, работает только в том случае, если мое приложение запускается после серверного приложения.Почему просмотр моего Android-приложения обновляется только при определенных обстоятельствах?

Сначала несколько деталей. Мое приложение и серверное приложение находятся на одном устройстве. Они взаимодействуют друг с другом через UDP (серверное приложение является портом приложения Windows). Мое приложение использует фрагменты, но представление, которое я хочу обновить, не находится в фрагменте. Теперь немного кода.

content_main.xml

<RelativeLayout> 
    <LinearLayout> 
     <ImageView 
      android:id="@+id/my_image_id" 
      android:src="@drawable/my_image" /> 
    </LinearLayout> 
    <LinearLayout> 
     <!-- fragment code here --> 
    </LinearLayout> 
</RelativeLayout> 

MainActivity.java

public class MainActivity extends AppCompatActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState){ 
     Listener myListener = new Listener(this); 
     Thread listenerThread = new Thread(myListener); 
     listenerThread.setName("My Listener Thread"); 
     listenerThread.start(); 
    } 
} 

Listener.java

public class Listener implements Runnable { 
    public Listener (Activity mainActivity) {this.mainActivity = mainActivity;} 
    private Activity mainActivity; 
    private ImageView myImageView; 
    private NewData newData; 

    @Override 
    public void run(){ 
     while(true){ 
      // Here is where my app gets the data from the server via UDP. 
      // This always works, I am always getting the correct data. 
      myImageView = (ImageView) mainActivity.findViewById(R.id.my_image_id); 
      mainActivity.runOnUiThread(new Runnable(){ 
       @Override 
       public void run(){ 
        if(newData == 1){ 
         myImageView.setImageResource(R.drawable.new_image_01); 
        } else if(newData == 2){ 
         myImageView.setImageResource(R.drawable.new_image_02); 
        } else { 
         myImageView.setImageResource(R.drawable.error_image); 
        } 
       } 
      }); 
     } 
    } 
} 

Как я са id, если я запустил приложение после серверного приложения, тогда все это работает отлично. Изображения всегда меняются при изменении новых данных. Однако, если я запустил приложение перед серверным приложением или перезапустил серверное приложение, пока мое приложение все еще работает, изображения никогда не изменятся, хотя я все равно получаю правильные данные от серверного приложения.

Что я могу сделать, чтобы убедиться, что просмотр может обновляться в любое время?

EDIT: Я переехал туда, где получаю представление за пределами цикла while (в качестве теста), и теперь код вообще не работает.

+3

что в то время как петля убивает котят. – Emmanuel

+1

Если у вас есть лучшее решение, я бы хотел его услышать. (Я серьезно, а не саркастично.) – Brian

+2

Значит, код связи? Возможно, приложение сервера запустило широковещательную рассылку, когда его приложение начнет прослушивать ваше приложение и запускает новое соединение в этот момент. –

ответ

0

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

public class TestThreadActivity extends AppCompatActivity { 

    private Button restart_Button; 
    private ImageView imageView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_test_thread); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.my_custom_toolbar); 
     setSupportActionBar(toolbar); 

     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

     initializeUI(); 
    } 

    private void initializeUI() { 
     restart_Button = (Button) findViewById(R.id.TestThreadActivity_restart_button); 
     imageView = (ImageView) findViewById(R.id.TestThreadActivity_imageView); 

     final Listener myListener = new Listener(this); 

     restart_Button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       imageView.setImageResource(R.drawable.piccolo); 
       final Thread listenerThread = new Thread(myListener); 
       listenerThread.setName("My Listener Thread"); 
       listenerThread.start(); 

      } 
     }); 

    } 

    public class Listener implements Runnable { 
     public Listener (Activity mainActivity) {this.mainActivity = mainActivity;} 
     private Activity mainActivity; 
     private ImageView myImageView; 
     int newData = 0; 

     @Override 
     public void run(){ 
      while(true){ 
       // Here is where my app gets the data from the server via UDP. 
       // This always works, I am always getting the correct data. 

       newData = (new Random()).nextInt(3); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

       myImageView = (ImageView) mainActivity.findViewById(R.id.TestThreadActivity_imageView); 
       mainActivity.runOnUiThread(new Runnable(){ 
        @Override 
        public void run(){ 
         System.out.println("newData: "+newData); 
         if(newData == 1){ 
          myImageView.setImageResource(R.drawable.gohan); 
         } else if(newData == 2){ 
          myImageView.setImageResource(R.drawable.goku); 
         } else { 
          myImageView.setImageResource(R.drawable.piccolo); 
         } 
        } 
       }); 
      } 
     } 
    } 

} 

activity_test_thread.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context="activities.list.first.TestThreadActivity"> 

    <include layout="@layout/my_custom_toolbar" /> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_margin="4dp" 
     android:orientation="vertical"> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal"> 


      <Button 
       android:id="@+id/TestThreadActivity_restart_button" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_margin="4dp" 
       android:layout_weight="0.5" 
       android:text="Start" 
       android:contentDescription="this will restart the thread" 
       android:textAllCaps="false" /> 

     </LinearLayout> 


     <ImageView 
      android:id="@+id/TestThreadActivity_imageView" 
      android:layout_width="match_parent" 
      android:layout_height="200dp" 
      android:src="@drawable/gohan" /> 
    </LinearLayout> 

</LinearLayout> 

Выход enter image description here