从 AsyncTask 更新 UI 并正确处理屏幕旋转
Update UI from AsyncTask and handle properly screen rotate
此代码在旋转屏幕时不起作用。
我尝试使用处理程序,但消息被发送到以前的 Activity(轮换之前)和新的 Activity.
¿一个线程如何向新 Activity 发送消息?
请不要建议避免旋转屏幕。
public class SampleActivity extends Activity {
TextView text;
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
text = new TextView(this);
text.setText("HELLO");
layout.addView(text);
if (savedInstanceState != null) {
text.setText(savedInstanceState.getString("text"));
}
setContentView(layout);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("text", text.getText().toString());
}
@Override
protected void onStart() {
super.onStart();
new CounterTask().execute();
}
public class CounterTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
publishProgress("Hello " + i);
} catch (Exception e) {
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
String str = values[0];
text.setText(str);
}
}
}
您可以使用 AsyncTaskLoader。它将处理您的 activity/fragment.
的所有旋转和生命周期事件
只需添加一些配置以防止在屏幕旋转时重新创建 activity,然后一切正常,因为您的 activity.
只有一个实例
将流畅的线条添加到 AndroidManifest.xml
中的 activity 标签
android:configChanges="orientation|keyboardHidden|screenSize"
这个方法给你SampleActivity.java
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// when screen rotated, this method will be called instead of onCreate
}
您可以 运行 保留片段中的 AsyncTask
。
public class TaskFragment extends Fragment {
private Callback mCallback;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (Callback) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement TaskFragment.Callback");
}
}
@Override
public void onDetach() {
super.onDetach();
mCallback = null;
}
public void execute(){
new CounterTask().execute();
}
public interface Callback {
void onTaskUpdate(String value);
}
public class CounterTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
publishProgress("Hello " + i);
} catch (Exception e) {
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
if(mCallback != null) {
String str = values[0];
mCallback.onTaskUpdate(str);
}
}
}
}
然后,在您的 activity 中实现回调并通过片段管理器添加片段。
public class SampleActivity extends Activity implements
TaskFragment.Callback {
private static final String TAG_TASK_FRAGMENT = "task_fragment";
private TaskFragment mTaskFragment;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
text = new TextView(this);
text.setText("HELLO");
layout.addView(text);
if (savedInstanceState != null) {
text.setText(savedInstanceState.getString("text"));
}
setContentView(layout);
FragmentManager fm = getFragmentManager();
mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);
if(mTaskFragment == null){
mTaskFragment = new TaskFragment();
fm.beginTransaction()
.add(mTaskFragment, TAG_TASK_FRAGMENT)
.commit();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("text", text.getText().toString());
}
@Override
protected void onStart() {
super.onStart();
mTaskFragment.execute();
}
@Override
public void onTaskUpdate(String value) {
text.setText(value);
}
}
此代码在旋转屏幕时不起作用。 我尝试使用处理程序,但消息被发送到以前的 Activity(轮换之前)和新的 Activity.
¿一个线程如何向新 Activity 发送消息? 请不要建议避免旋转屏幕。
public class SampleActivity extends Activity {
TextView text;
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
text = new TextView(this);
text.setText("HELLO");
layout.addView(text);
if (savedInstanceState != null) {
text.setText(savedInstanceState.getString("text"));
}
setContentView(layout);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("text", text.getText().toString());
}
@Override
protected void onStart() {
super.onStart();
new CounterTask().execute();
}
public class CounterTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
publishProgress("Hello " + i);
} catch (Exception e) {
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
String str = values[0];
text.setText(str);
}
}
}
您可以使用 AsyncTaskLoader。它将处理您的 activity/fragment.
的所有旋转和生命周期事件只需添加一些配置以防止在屏幕旋转时重新创建 activity,然后一切正常,因为您的 activity.
只有一个实例将流畅的线条添加到 AndroidManifest.xml
中的 activity 标签android:configChanges="orientation|keyboardHidden|screenSize"
这个方法给你SampleActivity.java
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// when screen rotated, this method will be called instead of onCreate
}
您可以 运行 保留片段中的 AsyncTask
。
public class TaskFragment extends Fragment {
private Callback mCallback;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (Callback) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement TaskFragment.Callback");
}
}
@Override
public void onDetach() {
super.onDetach();
mCallback = null;
}
public void execute(){
new CounterTask().execute();
}
public interface Callback {
void onTaskUpdate(String value);
}
public class CounterTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
publishProgress("Hello " + i);
} catch (Exception e) {
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
if(mCallback != null) {
String str = values[0];
mCallback.onTaskUpdate(str);
}
}
}
}
然后,在您的 activity 中实现回调并通过片段管理器添加片段。
public class SampleActivity extends Activity implements
TaskFragment.Callback {
private static final String TAG_TASK_FRAGMENT = "task_fragment";
private TaskFragment mTaskFragment;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
text = new TextView(this);
text.setText("HELLO");
layout.addView(text);
if (savedInstanceState != null) {
text.setText(savedInstanceState.getString("text"));
}
setContentView(layout);
FragmentManager fm = getFragmentManager();
mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);
if(mTaskFragment == null){
mTaskFragment = new TaskFragment();
fm.beginTransaction()
.add(mTaskFragment, TAG_TASK_FRAGMENT)
.commit();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("text", text.getText().toString());
}
@Override
protected void onStart() {
super.onStart();
mTaskFragment.execute();
}
@Override
public void onTaskUpdate(String value) {
text.setText(value);
}
}