我使用的是Android 2.3.3。 我在旋转屏幕后刷新活动的视图时遇到问题。
我的活动有一个变量(计数器),一个TextView(显示计数器值),一个按钮(增加计数器并显示它)和TimerTask(增加计数器并显示它)。 它工作正常。我的TextView在Button或TimerTask的每个事件之后显示一个新值。
直到我旋转手机才有效。 TimerTask的事件不再刷新我的TextView。按钮和旋转屏幕仍然可以修改我的视图。我的TimerTask仍然增加了我的变量,但屏幕上没有变化。我检查过,TimerTask仍然运行并执行。
这不是我真正的项目,它只是我的错误的一部分。
我唯一的活动:
package com.test;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class TestRefreshActivity extends Activity {
static TimerTask mTimerTask=null;
static Timer t=new Timer();
final Handler handler = new Handler();
static int counter=0;
//-------------------------------------------------
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create and run the timer
if(mTimerTask==null){
Log.d("Test","new TimerTask");
mTimerTask = new TimerTask() {
public void run() {
handler.post(new Runnable(){
public void run(){
counter++;
refreshCounter();
Log.d("TIMER", "TimerTask run");
}
});
}
};
t.schedule(mTimerTask, 500, 3000);
}
Log.d("Test","--onCreate--");
refreshCounter();
}
//-------------------------------------------------
@Override
public void onBackPressed() {
super.onBackPressed();
mTimerTask.cancel();
TestRefreshActivity.this.finish();
}
//-------------------------------------------------
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Test","--onDestroy--");
}
//-------------------------------------------------
public void onBtnClick(View view){
counter++;
refreshCounter();
}
//-------------------------------------------------
//the only function which refreshes the TextView
private void refreshCounter(){
Runnable run = new Runnable(){
public void run(){
TextView textView = (TextView)findViewById(R.id.textView1);
textView.setText("counter="+counter);
textView.invalidate();
}
};
synchronized(run){
TestRefreshActivity.this.runOnUiThread(run);
}
}
}
我唯一的观点:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onBtnClick"
android:text="Button" />
</LinearLayout>
我不明白为什么我的TimerTask在旋转后无法改变视图。我知道,旋转会破坏我的活动以重新创建它,但只有静态变量才能生存。
感谢您的帮助。
此致
答案 0 :(得分:0)
android:configChanges="keyboardHidden|orientation"
- 这是一个糟糕的解决方案,受到指导方针的劝阻。它只会保存你的屏幕旋转,但你的应用程序仍然无法使用,因为你的活动会被它在后台安装时杀死。
看看你做了什么。您提供对静态计时器的处理程序的引用。旋转手机时,会重新创建活动(意味着一个被销毁,另一个被创建)。你的活动被破坏了,但静态成员仍然活着,他们仍然持有对死亡活动的处理程序的引用。
然后使用新的处理程序创建一个新活动,但是你的timertask对此一无所知。
所以你有一个更新无效处理程序的静态计时器,以及什么都不做的活动。
我会丢弃静态并将onSaveInstanceState中的当前计时器值保存在bundle中。
或者(甚至对你来说更容易)在你的TimerTask中为处理程序创建一个setter,当你这样做时检查if(mTimerTask==null){
并看看,该计时器已经实例化,在其中设置一个新的处理程序({{1因此,当创建新活动时,您的timertask将在新的处理程序中发布。
答案 1 :(得分:-2)
打开您的Android清单文件并更改活动代码,如下所示
<activity android:name=".aaa"
android:configChanges="keyboardHidden|orientation"
android:label="@string/app_name"></activity>