Android:Viewpager、线程和方向改变

标签 android multithreading android-fragments

我对 Android 编程还是很陌生,现在我正在为屏幕方向的变化而苦苦挣扎。

我正在使用带有 FragmentPagerAdapter 的 viewPager,如 Android Developers 中所述显示两个使用选项卡访问的 fragment 。

在 Fragment1 中,按下按钮时会启动一个新线程。该线程计算数据并不断更新 UI(使用 UI 线程)。再次按下按钮时,标志设置为 false,停止线程。当滑动到 Fragment2 或按下 home 键时,线程继续运行。当按下后退按钮时, Activity 和 fragment 被销毁,线程也被销毁(我想?)。那将是预期的行为。

我想了解当屏幕改变方向时到底发生了什么。如果它正在运行, fragment 和我的线程会发生什么情况?您能否指向一个链接,解释在方向更改后我应该如何继续保持线程运行和更新 UI?

编辑:我找到了一种方法来获得我想要的行为(如下所述)。不过,我仍然不确定幕后到底发生了什么。

我只需要将这一行放在 fragment 构造函数中:

savedInstanceState(true);

通过这一行,屏幕旋转后UI仍然更新。由于按钮文本在激活时会发生变化,因此我还必须在 fragment onCreateView() 方法中添加类似这样的内容:

if(flag) {
    mStartButton.setText();
}

这些问题对我有帮助:

编辑 2:这是关于我的代码的一些附加信息。在我的 fragment OnCreateView() 中,我有一个简单按钮的监听器:

// Start-Stop button listener
mStartButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (!mIsRunning) { // START
            // New thread
            Thread myThread = new Thread(new Runnable() {
                public void run() {
                    runFunction();
                }
            });
            myThread.start();

            mIsRunning = true;
            mStartButton.setText(getString(R.string.stop));
        }
        else { // STOP
            mIsRunning = false;
            mStartButton.setText(getString(R.string.start));
        }
    }
});

runFunction() 定义如下:

private void runFunction() {
    while(mIsRunning) {
        // Do something
    }
}

最佳答案

处理线程中断

我建议像这样更改 onClickrunFunction()(source):

// in fragments oncreate
myThread = new Thread(new Runnable() {
    public void run() {
        runFunction();
    }
});

// Start-Stop button listener
mStartButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (!mIsRunning) { // START
            myThread.start();
            mStartButton.setText(getString(R.string.stop));
        } else { // STOP
            myThread.interrupt();
            mStartButton.setText(getString(R.string.start));
        }
        mIsRunning = !mIsRunning
    }
});

runFunction() 定义如下:

private void runFunction() {
    while(!Thread.currentThread().isInterrupted()) {
        // Do something
    }
}

保证线程会在您单击按钮后立即停止。在 gui 线程和 myThread 之间存在竞争条件。在您的版本中,假设您单击了按钮并发生了上下文切换。您的线程已在线激活

while(mIsRunning) {

并且 bool 值被检查为真。上下文切换发生并且 gui 线程使值 false。上下文切换又发生一次,线程继续运行而不检查 bool 值。它仅在单次迭代后停止。这种情况可能很少见,您不必担心这个问题。

处理方向变化

当您更改方向时,将调用 onSaveInstanceState。您可以在此处保存重新创建 Activity 后要使用的变量。

public void onSaveInstanceState(Bundle savedState) {
    super.onSaveInstanceState(savedState);
    savedState.putBool("mIsRunning", mIsRunning);
}

方向改变后再次调用onCreate

public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myThread = new Thread(new Runnable() {
        public void run() {
            runFunction();
        }
    });

    if (savedInstanceState != null) {
        mIsRunning = savedInstanceState.getBool("mIsRunning");
        if (mIsRunning) {
           myThread.start();
           mStartButton.setText(getString(R.string.stop));
        }
    }
    ...
}

关于Android:Viewpager、线程和方向改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23071796/

相关文章:

android - 自定义 View android 中的 "FINGERPRINT_ERROR_CANCELED"错误

android - 如何在对话框中添加多个 TextView

php - 无法从线程访问全局变量?

android - 向我的 Activity/fragment 添加绘图/绘画功能

android - 如何制作 ViewPager 循环?

android - Gradle Flavor 明智地更改 packageName 和 applicationId

android - 更改 ListView 项目的文本颜色

multithreading - 一个进程之间的线程可见性

c++ - Quest 库(Quest 身份验证服务)线程安全吗?

android - 抽屉导航项目是具有选项卡的 fragment