runOnUiThread parça halinde


122

Bir Aktiviteyi parçaya dönüştürmeye çalışıyorum. Hata işareti açık runOnUiThread. geçmişte:

GoogleActivityV2, Activity'den genişler. ExecuteTask sınıfında runOnUiThread. sınıf ExecuteTask, etkinlik üzerinde yuvalanmış.

(Tamam çalıştır) şimdi:

GoogleActivityV2, Fragment'den genişler. ExecuteTask sınıfında runOnUiThread. sınıf ExecuteTask, etkinlik üzerinde yuvalanmış. (RunOnUiThread'de hata)

işte kodum

public class GoogleActivityV2 extends SherlockMapFragment implements OnMapClickListener , OnMapLongClickListener , OnCameraChangeListener , TextWatcher {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        View rootView = inflater.inflate(R.layout.activity_googlev2, container, false);
        Init();
        adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line);
        textView = (AutoCompleteTextView) getView().findViewById(R.id.autoCompleteTextView1);
        return rootView;
    }

    public void onCameraChange(CameraPosition arg0){
        // TODO Auto-generated method stub
    }

    public void onMapLongClick(LatLng arg0){
        llLoc = arg0;
        stCommand = "onTouchEvent";
        lp = new ExecuteTask();
        lp.execute();
    }

    public void onMapClick(LatLng arg0){
        // TODO Auto-generated method stub
    }

    class ExecuteTask extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute(){
            super.onPreExecute();
            if(stCommand.compareTo("AutoCompleteTextView") != 0) {
                pDialog = new ProgressDialog(getActivity());
                pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading ..."));
                pDialog.setIndeterminate(false);
                pDialog.setCancelable(false);
                pDialog.show();
            }
        }

        protected String doInBackground(String ... args){
            do something
            return null;
        }

        @Override
        protected void onPostExecute(String file_url){
            if(stCommand.compareTo("AutoCompleteTextView") != 0) pDialog.dismiss();
            runOnUiThread(new Runnable() {
                public void run(){
                    do something
                }
            });
        }
    }
    public void afterTextChanged(Editable s){
        // TODO Auto-generated method stub
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after){
        // TODO Auto-generated method stub
    }

    public void onTextChanged(CharSequence s, int start, int before, int count){
        // TODO Auto-generated method stub
    }
}

hata diyor ki: Eclipse Hatası

bu hatayı nasıl düzeltebilirim?


8
OnPostExecute içine yazdığınız kod zaten ana iş parçacığı içinde çalışıyor. Öte yandan, runOnUiThread () işlevini çağırmanıza gerek yoktur.
rciovati

@rciovati "bir şeyler yap" onPostExecute farklıdır
Tai Dao

Yanıtlar:


272

Bunu dene: getActivity().runOnUiThread(new Runnable...

Nedeni:

1) thisaramanızdaki örtük runOnUiThreadkısım AsyncTask'e atıfta bulunuyor, parçanıza değil.

2) FragmentrunOnUiThread içermiyor.

Ancak Activityöyle.

Not Activitysadece yürütür Runnableana iş parçacığı üzerinde zaten iseniz, aksi takdirde kullanır Handler. Bir uygulayabilirsinizHandler sen bağlamında ilgili endişe istemiyorsanız eğer fragmanında this, çok kolay aslında:

// 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.

DÜZENLEME: @rciovati doğru, içeridesiniz onPostExecute, bu zaten ana başlıkta.


3
Bazen getActivity (). RunOnUiThread, NullPointerException ile sonuçlanır. Açıklar mısın
geliştirici1011

1
@ developer1011 parça etkinlikten ayrıldığında gerçekleşecek. Bu zaman uyumsuz görevlerde yaygındır, çünkü etkinlik uzun süren işlem sırasında yok edilmiş olabilir, dolayısıyla artık yok get. Her zaman önce boş değeri kontrol edin.
bclymer

4
Teşekkürler. Ben çevrili getActivity().runOnUiThreadolan if (isAdded())ve iyi çalışıyor
developer1011

1
@bclymer, bu cevabın Google'da UI iş parçacığı için fiili referans olduğu göz önüne alındığında, son bölümde biraz daha ayrıntı (aynı işi yapan bir İşleyicinin nasıl uygulanacağı) güzel olurdu!
LS97

4

Xamarin.Android'de

Parça için:

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

Aktivite için:

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

Mutlu kodlama :-)


4

Bir Kotlin uzantı işlevi kullanın

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

Sonra, herhangi birinde Fragmentarayabilirsin runOnUiThread. Bu, aramaların faaliyetler ve parçalar arasında tutarlı olmasını sağlar.

runOnUiThread {
    // Call your code here
}

NOT : FragmentArtık bir'e bağlı Activitydeğilse, geri arama çağrılmayacak ve istisna atılmayacaktır.

Bu stile herhangi bir yerden erişmek istiyorsanız, ortak bir nesne ekleyebilir ve yöntemi içe aktarabilirsiniz:

object ThreadUtil {
    private val handler = Handler(Looper.getMainLooper())

    fun runOnUiThread(action: () -> Unit) {
        if (Looper.myLooper() != Looper.getMainLooper()) {
            handler.post(action)
        } else {
            action.invoke()
        }
    }
}

1
Kotlin uzantı işlevlerini kesinlikle seviyorum.
OhhhThatVarun

2

Bunu bir parçada Tarih ve Saat almak için kullandım.

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

1

Ayrıca, başka herhangi bir iş parçacığındaki görünümü kullanarak runnable'ı da gönderebilirsiniz. Ancak görünümün boş olmadığından emin olun:

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

Belgelere göre:

"Boolean post (Çalıştırılabilir eylem) Çalıştırılabilir öğenin ileti kuyruğuna eklenmesine neden olur. Çalıştırılabilir, kullanıcı arabirimi iş parçacığında çalıştırılır."

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.