我正在开发一款表现奇怪的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循环之外的地方(作为测试),现在代码根本不起作用。
答案 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>