简体   繁体   English

在另一个线程中处理UI组件

[英]Handling UI components in another thread

I want to change few components in another thread. 我想在另一个线程中更改几个组件。 I did it, but I don't know is it good enough (or too bad). 我做到了,但我不知道它是否足够好(或太糟糕)。 This is how I do: 这是我的方法:

public class FullMapFragment extends Fragment {    

    private AlertDialog alertDialog; //volatile?
    ...

Runnable class for handler: 处理程序的可运行类:

public class ShowAlertDialog implements Runnable{

    private AlertDialog alertDialog;

    public  ShowAlertDialog (AlertDialog alertDialog)
    {
        this.alertDialog=alertDialog;
    }
    public void run()
    {
         //do something with dialog
    }

In another thread: 在另一个线程中:

public class UpdateMapRunnable implements Runnable {

    public UpdateMapRunnable(FullMapFragment fragment) {
        this.fragment = fragment;

    }

    private FullMapFragment fragment; //volatile?

    private final Handler uiHandler = new Handler();

    @Override
    public void run() {     
        uiHandler.post(new ShowAlertDialog (fragment.getAlertDialog()));            
    }

Is that ok? 这可以吗? Do I have to add volatile modificator to those fields? 我是否必须在这些字段中添加易失性修饰符?

You should never modify UI components outside UI thread . 永远不要在UI线程之外修改UI组件 Because if you'll change Dialog's components in the working thread while it is being rendered in AWT EQ, you will get an error and volatile won't help. 因为如果在AWT EQ中渲染Dialog时在工作线程中更改其组件,则会收到错误消息,而volatile将无济于事。 But if you just want dialog to be accessible in another thread to prepare it, and you surely will show it only after all modifications, just make it final, it will be enough. 但是,如果您只希望对话框可以在另一个线程中访问以进行准备,并且您肯定只在进行所有修改后才显示该对话框,只需使其最终完成就可以了。 Again, volatile won't help, as it only makes pointer volatile, not the entire object . 再说一次,volatile将无济于事,因为它只会使指针变为volatile,而不是整个对象 And if you need concurrent changes on Dialog's properties, you need to sync it's fields/methods. 并且,如果您需要同时更改Dialog的属性,则需要同步它的字段/方法。 Type of sync will vary depending on access mode. 同步类型会因访问模式而异。 If one thread writes and others only read, volatile is ok, if more than 1 writer, you'll need something more strict, like Atomic or synchronized. 如果一个线程写而其他线程只读,则volatile是可以的,如果写线程超过1,则需要更严格的操作,例如Atomic或Synchronized。

So, you can: 所以你可以:

1) / for concurrent changes / create a data model, which you compute and change (which can be a long work) and then in UI thread you only modify UI components corresponding to model state (which is fast). 1)/ 对于并发更改 /创建一个数据模型,您可以对其进行计算和更改(这可能需要很长时间),然后在UI线程中仅修改与模型状态相对应的UI组件(速度很快)。 Here you will need some synchronization. 在这里,您将需要一些同步。

2) / for non-concurrent changes / send a runnable code to UI thread to do all the work (in case you need threading, but not for UI work) like that: 2)/ 用于非并发更改 /将可运行的代码发送到UI线程以完成所有工作(以防需要线程化,但不需要UI工作),如下所示:

EventQueue.invokeLater( ()->{ /*your work here*/ } );

3) do both 1 and 2. Almost all cases finally come to this. 3)同时执行1和2。几乎所有情况都最终出现了。

If everything is written right you will need synchronization only when where is more than 1 worker (non-ui) thread. 如果一切都写正确 ,则仅在凡有1个以上工作线程(非UI)的情况下才需要同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM