为什么我的Android应用视图仅在特定情况下更新?

时间:2016-01-27 20:52:08

标签: android multithreading android-layout

我正在开发一款表现奇怪的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);
                    }
                }
            });
        }
    }
}

就像我说的,如果我在服务器应用程序之后启动我的应用程序,那么这一切都完美无缺。当新数据发生变化时,图像总是会改变。但是,如果我在服务器应用程序之前启动我的应用程序,或者在我的应用程序仍在运行时重新启动服务器应用程序,那么即使我仍然从服务器应用程序获取正确的数据,图像也不会更改。

我可以做些什么来确保视图可以随时更新?

编辑:我移动到了将视图移到while循环之外的地方(作为测试),现在代码根本不起作用。

1 个答案:

答案 0 :(得分: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