runOnUiThread in fragment

前端 未结 6 568
囚心锁ツ
囚心锁ツ 2020-11-30 21:49

I\'m trying to convert an Activity to fragment. The error mark on runOnUiThread. on the past:

GoogleActivityV2 extends from Activity. ru

相关标签:
6条回答
  • 2020-11-30 22:01

    Try this: getActivity().runOnUiThread(new Runnable...

    It's because:

    1) the implicit this in your call to runOnUiThread is referring to AsyncTask, not your fragment.

    2) Fragment doesn't have runOnUiThread.

    However, Activity does.

    Note that Activity just executes the Runnable if you're already on the main thread, otherwise it uses a Handler. You can implement a Handler in your fragment if you don't want to worry about the context of this, it's actually very easy:

    // A class instance
    private Handler mHandler = new Handler(Looper.getMainLooper());
    
    // anywhere else in your code
    mHandler.post(<your runnable>);
    // ^ this will always be run on the next run loop on the main thread.
    

    EDIT: @rciovati is right, you are in onPostExecute, that's already on the main thread.

    0 讨论(0)
  • 2020-11-30 22:02

    I used this for getting Date and Time in a fragment.

    private Handler mHandler = new Handler(Looper.getMainLooper());
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.fragment_head_screen, container, false);
    
        dateTextView =  root.findViewById(R.id.dateView);
        hourTv = root.findViewById(R.id.hourView);
    
            Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    while (!isInterrupted()) {
                        Thread.sleep(1000);
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                //Calendario para obtener fecha & hora
                                Date currentTime = Calendar.getInstance().getTime();
                                SimpleDateFormat date_sdf = new SimpleDateFormat("dd/MM/yyyy");
                                SimpleDateFormat hour_sdf = new SimpleDateFormat("HH:mm a");
    
                                String currentDate = date_sdf.format(currentTime);
                                String currentHour = hour_sdf.format(currentTime);
    
                                dateTextView.setText(currentDate);
                                hourTv.setText(currentHour);
                            }
                        });
                    }
                } catch (InterruptedException e) {
                    Log.v("InterruptedException", e.getMessage());
                }
            }
        };
    }
    
    0 讨论(0)
  • 2020-11-30 22:17

    For Kotlin on fragment just do this

    activity?.runOnUiThread(Runnable {
            //on main thread
        })
    
    0 讨论(0)
  • 2020-11-30 22:18

    In Xamarin.Android

    For Fragment:

    this.Activity.RunOnUiThread(() => { yourtextbox.Text="Hello"; });
    

    For Activity:

    RunOnUiThread(() => { yourtextbox.Text="Hello"; });
    

    Happy coding :-)

    0 讨论(0)
  • 2020-11-30 22:20

    You can also post runnable using the view from any other thread. But be sure that the view is not null:

     tView.post(new Runnable() {
                        @Override
                        public void run() {
                            tView.setText("Success");
                        }
                    });
    

    According to the Documentation:

    "boolean post (Runnable action) Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread."

    0 讨论(0)
  • 2020-11-30 22:27

    Use a Kotlin extension function

    fun Fragment?.runOnUiThread(action: () -> Unit) {
        this ?: return
        if (!isAdded) return // Fragment not attached to an Activity
        activity?.runOnUiThread(action)
    }
    

    Then, in any Fragment you can just call runOnUiThread. This keeps calls consistent across activities and fragments.

    runOnUiThread {
        // Call your code here
    }
    

    NOTE: If Fragment is no longer attached to an Activity, callback will not be called and no exception will be thrown

    If you want to access this style from anywhere, you can add a common object and import the method:

    object ThreadUtil {
        private val handler = Handler(Looper.getMainLooper())
    
        fun runOnUiThread(action: () -> Unit) {
            if (Looper.myLooper() != Looper.getMainLooper()) {
                handler.post(action)
            } else {
                action.invoke()
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题