从 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);
    }
}