Hoe gebruiken we runOnUiThread in Android?

Ik ben nieuw bij Android en ik probeer de UI-Thread te gebruiken, dus ik heb een eenvoudige testactiviteit geschreven. Maar ik denk dat ik iets verkeerd heb begrepen, want bij het klikken op de knop reageert de app niet meer

public class TestActivity extends Activity {
    Button btn;
    int i = 0;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button)findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                runThread();
            }
        });
    }
    private void runThread(){
        runOnUiThread (new Thread(new Runnable() {  
            public void run() {
                while(i++ < 1000){
                    btn.setText("#"+i);
                    try {
                        Thread.sleep(300);
                    } 
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
             }
        }));
    }
}

Antwoord 1, autoriteit 100%

Hieronder is het gecorrigeerde fragment van de functie runThread.

private void runThread() {
    new Thread() {
        public void run() {
            while (i++ < 1000) {
                try {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            btn.setText("#" + i);
                        }
                    });
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}

Antwoord 2, autoriteit 44%

Wikkel het gewoon in als een functie en roep deze functie dan aan vanuit je achtergrondthread.

public void debugMsg(String msg) {
    final String str = msg;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mInfo.setText(str);
        }
    });
}

Antwoord 3, autoriteit 13%

Je hebt het van voren naar achteren. Uw klik op een knop resulteert in een aanroep van runOnUiThread(), maar dit is niet nodig, aangezien de klikhandler al actief is op de UI-thread. Vervolgens lanceert uw code in runOnUiThread()een nieuwe achtergrondthread, waarin u UI-bewerkingen probeert uit te voeren, die vervolgens mislukken.

Start in plaats daarvan de achtergrondthread rechtstreeks vanuit uw klikhandler. Wikkel vervolgens de aanroepen naar btn.setText()in een aanroep naar runOnUiThread().


Antwoord 4, autoriteit 7%

runOnUiThread(new Runnable() {
                public void run() {
                //Do something on UiThread
            }
        });

Antwoord 5, autoriteit 5%

Er zijn verschillende technieken die runOnUiThread()gebruiken, laten we ze allemaal bekijken

Dit is mijn hoofdthread (UI-thread) genaamd AndroidBasicThreadActivityen ik ga het op verschillende manieren updaten vanuit een werkthread –

public class AndroidBasicThreadActivity extends AppCompatActivity
{
    public static TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_android_basic_thread);
        textView = (TextView) findViewById(R.id.textview);
        MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this);
        Thread t1 = new Thread(myTask, "Bajrang");
        t1.start();
    }
}

1.) Door de instantie van Activiteit door te geven als argument op werkthread

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {
        //perform heavy task here and finally update the UI with result this way - 
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
            }
        });
    }
}

2.) Door gebruik te maken van de post (Uitvoerbaar uitvoerbare) methode van View in werkthread

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {
     //perform heavy task here and finally update the UI with result this way - 
       AndroidBasicThreadActivity.textView.post(new Runnable()
      { 
        @Override
        public void run()
        {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });
    }
}

3.) Door de klasse Handler van het android.os-pakket te gebruiken
Als we de context (this/ getApplicationContext()) of de instantie van Activity (AndroidBasicThreadActivity.this) niet hebben, moeten we Handler gebruiken klasse zoals hieronder –

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
   public void run()
  {
  //perform heavy task here and finally update the UI with result this way - 
  new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });
  }
}

Antwoord 6, autoriteit 5%

Als je in fragment gebruikt, schrijf dan gewoon

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // Do something on UiThread
    }
});

Antwoord 7

We gebruiken Worker Thread om Apps soepeler te maken en ANR’s te vermijden. Mogelijk moeten we de gebruikersinterface bijwerken na het zware proces in worker Tread.
De gebruikersinterface kan alleen worden bijgewerkt vanuit de UI-thread. In dergelijke gevallen gebruiken we Handler of runOnUiThread, beide hebben een Runnable run-methode die wordt uitgevoerd in UI Thread.
De onClick-methode wordt uitgevoerd in UI-thread, dus u hoeft runOnUiThread hier niet te gebruiken.

Kotlin gebruiken

Tijdens activiteit,

this.runOnUiThread {
      // Do stuff
}

Van Fragment,

activity?.runOnUiThread {
      // Do stuff
}

Java gebruiken,

this.runOnUiThread(new Runnable() {
     void run() {
         // Do stuff
     }
});

Antwoord 8

dit:

@UiThread
    public void logMsg(final String msg) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Log.d("UI thread", "I am the UI thread");
            }
        });
    }

Antwoord 9

U kunt van dit voorbeeld gebruiken:

In het volgende voorbeeld gaan we deze faciliteit gebruiken om het resultaat van a . te publiceren
zoeken op synoniemen die is verwerkt door een achtergrondthread.

Om het doel te bereiken tijdens het terugbellen van de activiteit OnCreate, zullen we instellen:
onClickListener om searchTask uit te voeren op een aangemaakte thread.

Wanneer de gebruiker op de knop Zoeken klikt, maken we een Runnable-anoniem
klasse die zoekt naar het woord getypt in R.id.wordEt EditText en start de
thread om Runnable uit te voeren.

Als de zoekopdracht is voltooid, maken we een exemplaar van Runnable SetSynonymResult
om het resultaat terug te publiceren op het synoniem TextView via de UI-thread.

Deze techniek is soms niet de handigste, vooral als we dat niet doen
toegang hebben tot een activiteitsinstantie; daarom zijn we in de volgende hoofdstukken
gaan eenvoudigere en schonere technieken bespreken om de gebruikersinterface vanaf een achtergrond bij te werken
computertaak.

public class MainActivity extends AppCompatActivity {
    class SetSynonymResult implements Runnable {
        String synonym;
        SetSynonymResult(String synonym) {
            this.synonym = synonym;
        }
        public void run() {
            Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d",
                    synonym, Thread.currentThread().getId()) + " !");
            TextView tv = (TextView) findViewById(R.id.synonymTv);
            tv.setText(this.synonym);
        }
    }
    ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button search = (Button) findViewById(R.id.searchBut);
        final EditText word = (EditText) findViewById(R.id.wordEt);
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Runnable searchTask = new Runnable() {
                    @Override
                    public void run() {
                        String result = searchSynomim(word.getText().toString());
                        Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s",
                                word.getText(), Thread.currentThread().getName()));
                        runOnUiThread(new SetSynonymResult(result));
                    }
                };
                Thread thread = new Thread(searchTask);
                thread.start();
            }
        });
    }
    static int i = 0;
    String searchSynomim(String word) {
        return ++i % 2 == 0 ? "fake" : "mock";
    }
}

Bron:

asynchrone Android-programmering Helder Vasconcelos


Antwoord 10

Dit is hoe ik het gebruik:

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                //Do something on UiThread
            }
        });

Antwoord 11

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gifImageView = (GifImageView) findViewById(R.id.GifImageView);
        gifImageView.setGifImageResource(R.drawable.success1);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //dummy delay for 2 second
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //update ui on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        gifImageView.setGifImageResource(R.drawable.success);
                    }
                });
            }
        }).start();
    }

Antwoord 12

Probeer dit: getActivity().runOnUiThread(new Runnable...

Het is omdat:

1) het impliciete dit in uw aanroep naar runOnUiThreadverwijst naar AsyncTask, niet naar uw fragment.

2) Fragment heeft geen runOnUiThread.

Activiteit echter wel.

Houd er rekening mee dat Activity de Runnable alleen uitvoert als je al in de hoofdthread zit, anders gebruikt het een Handler. Je kunt een Handler in je fragment implementeren als je je geen zorgen wilt maken over de context hiervan, het is eigenlijk heel eenvoudig:

// Een klasse-instantie

private Handler mHandler = new Handler(Looper.getMainLooper());

// ergens anders in je code

mHandler.post(<your runnable>);

// ^ dit wordt altijd uitgevoerd in de volgende run-lus op de hoofdthread.

Other episodes