Android:Viewpager,线程和方向更改

时间:2014-04-14 22:53:55

标签: android multithreading android-fragments

我仍然对Android编程很陌生,现在我正在努力改变屏幕方向。

我正在使用带有FragmentPagerAdapter的viewPager,如Android Developers所述,显示使用标签访问的两个片段。

在Fragment1中,按下按钮时会启动一个新线程。该线程计算数据并不断更新UI(使用UI线程)。再次按下该按钮时,标志设置为false,停止该线程。当滑动到Fragment2或按下主页按钮时,线程继续运行。当按下后退按钮时,活动和片段被破坏,线程也是如此(我想?)。这将是预期的行为。

我想了解当屏幕改变方向时会发生什么。片段和我的线程如果运行会发生什么?您能否指点我一个链接,解释如何在方向更改后继续保持线程运行并更新UI?

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

我只需将此行放在片段构造函数中:

savedInstanceState(true);

使用此行,屏幕旋转后UI仍会更新。由于按钮文本在激活时被更改,我还必须在片段onCreateView()方法中添加这样的内容:

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

这些是帮助我的问题:

编辑2:以下是有关我的代码的一些其他信息。在我的片段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
    }
}

1 个答案:

答案 0 :(得分:2)

处理线程中断

我建议像这样更改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) {

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

处理方向更改

当您更改方向时,会调用onSaveInstanceState。在这里,您可以在重新创建活动后保存要使用的变量。

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