后台线程中的进度条.setProgress(variable)

Posted

技术标签:

【中文标题】后台线程中的进度条.setProgress(variable)【英文标题】:Progress bar.setProgress(variable) in a background thread 【发布时间】:2020-07-06 05:13:38 【问题描述】:

这是我在堆栈上的第一个问题(伟大的社区,谢谢!)

所以,我有这个问题:

我正在开发一个带有选项卡布局的 android 应用程序。每当我导航到“状态”选项卡时,我想显示一个根据变量值更新的循环 ProgressBar。我们称这个变量为 prog。此外,我想在 ProgressBar 的中心显示一个 TextView,它显示相同的 prog 值。

我想出了这部分代码:

public class StatusFragment extends Fragment


    private ProgressBar torqueRefProgressBar;
    private TextView torqueRefTextView;


    RunningThreadExample r;
    private Thread t1;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    
        //Inflate the layout for this fragment
        return ...;

    

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState)
    
        // Initializations and other parts not relevant for the question...

        this.torqueRefProgressBar   =   getView().findViewById(R.id.torqueRefProgressBar);

        this.torqueRefTextView      =   getView().findViewById(R.id.torqueRefTextView);


        t1 = new Thread( this.torqueRefProgressBar, this.torqueRefTextView)); // passing arguments by value but values are references to the objects, therefore I'm passing by ref

        t1.start();


    


在这个 Fragment 中,我创建 ProgressBar 和 TextView,然后将它们传递给 Runnable,如下所示

public class RunningThreadExample implements Runnable


    ProgressBar torqueRefProgBar_thread;
    TextView torqueRefTextView_thread;

    public RunningThreadExample(ProgressBar progressBar, TextView textView)
    
        this.torqueRefProgBar_thread = progressBar;
        this.torqueRefTextView_thread = textView;
        this.endScale = this.torqueRefProgBar_thread.getMax();
    

    @Override
    public void run()
    
        android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

       float i = 0;

       double temp = 0;


        while(Running)
        
            try
            
                Thread.sleep(1000/60); // update freq 60Hz
            
            catch (InterruptedException e)
            
                e.printStackTrace();
            

            temp = getCurrentVariableValue(); // Not shown here (returns a double)

            this.torqueRefProgBar_thread.setProgress((int) temp);
            this.torqueRefTextView_thread.setText(String.valueOf(temp));

        

        Log.i(INFO_TAG,"Finishing thread!!!!!");

    





我希望此更新在应用程序运行时一直运行(因此我忽略了 AsyncTask)。一段时间后,ProgressBar 会停止更新,而 TextView 会继续工作而没有任何问题。

我一直在阅读,可能的原因可能是调用 setProgress(temp) 可能会卡住 UI。但是,当 TextView 仍在工作时,我无法理解。

您能建议一种更好的方法来更新进度条吗?

谢谢!

【问题讨论】:

【参考方案1】:

看到这个帖子:

Android basics: running code in the UI thread

总而言之,Android 需要特定类型和部分的代码才能在特定上下文中运行。许多工具(例如处理程序)可用于帮助完成这些任务,但一开始很难学习。

【讨论】:

谢谢,处理程序确实为我工作。我没有意识到将 UI 组件作为被调用的可运行对象的构造函数的参数传递并将更新委托给主 Looper 就足够了。你的建议真的很棒【参考方案2】:

您不能从除主线程之外的任何线程影响视图。在run() 方法中执行以下操作

runOnUiThread(new Runnable()  
// 
run()

 this.torqueRefProgBar_thread.setProgress((int) temp);
            this.torqueRefTextView_thread.setText(String.valueOf(temp));
);

【讨论】:

抱歉,我没有找到联系runOnUiMethod() 的地方。我试过在我的run() 内部打电话,但没有定义

以上是关于后台线程中的进度条.setProgress(variable)的主要内容,如果未能解决你的问题,请参考以下文章

长按如何使进度条变化Android

我想在 30 秒后重新启动一个圆形进度条

VB.NET 中带有后台工作者的字幕进度条

3.4 复杂进度对话框

需要有关 gtkmm 中的多线程的帮助

是否可以在后台线程中填充 ObjectListView?