Multithread-Zusammenfassung finden Sie hier
Ich fürchte, also kurz gesagt, ein Memo über die Multithread-Verarbeitung
■ ** Thread ** Klassenerweiterung | ** Runnable ** Schnittstellenvererbung ** Kommunikation mit UI-Thread ** view#post(Runnable) View#postDelayed(Runnable.long) runOnUiThread(Runnable) ■ ** AsyncTask ** -Klasse ** Verarbeitung und UI-Thread-Kommunikation ** Mit execute (), doInBackground (), postExecute () usw. ■ ** Handler ** Klasse ** Realisiert die Kommunikation zwischen mehreren Threads (OK, auch wenn es sich nicht um einen UI-Thread handelt) ** Message Runnable
■Thread(Thread/Runnable) Android läuft auf einem Linux-Prozess mit einem Thread. Dieser Thread wird als einzelner Thread bezeichnet, und MainActivity.java wird in einem einzelnen Thread ausgeführt. Hier wird der Thread, auf dem MainActivity ausgeführt wird, als Hauptthread bezeichnet und beschrieben. Nur der Hauptthread kann UI-Teile direkt verarbeiten. Um UI-Teile von anderen Threads aus zu bedienen, wird eine spezielle Methode verwendet.
MainActivity spielt die Rolle einer vom Benutzer bedienten Schnittstelle. Wenn der Hauptthread also eine zeitaufwändige Verarbeitung durchführt, reagiert der Betriebsbildschirm nicht mehr oder die Gesamtverarbeitung verlangsamt sich, was die Verwendung erschwert. Ich werde am Ende.
Um die Benutzerfreundlichkeit der App zu gewährleisten, müssen Entwurfsprozesse, die nicht mit Benutzervorgängen zusammenhängen, separat über einen separaten Thread (Multithread) verarbeitet werden. Es scheint, dass eine andere Thread-Verarbeitung entweder über die Thread-Klasse oder die Runnable-Schnittstelle erfolgt.
**
Da ein anderer Thread ebenfalls auf demselben Linux-Prozess wie der Haupt-Thread verarbeitet wird, sollten Sie bei Problemen mit einem einzelnen Prozess einen anderen Linux-Prozess (Multi-Prozess) starten und bei Bedarf einen weiteren Thread erstellen. Vielleicht (Manifest.java).
□Thread
In einer Unterklasse von Thread
public void onCreate(){
SubThread subThread = new SubThread();
subThread.start();
}
class SubThread extends Thread{
public void run(){
// todo
}
}
□Runnable Obwohl es sich um eine Beschreibung von Runnable handelt, gibt es drei bekannte Beschreibungsmethoden.
Anonym funktionsfähig
new Thread(new Runnable(){
@Override
public void run(){
// todo
}
}).start();
Verwenden einer Thread-Instanz
public void onCreate(){
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
Thread.start();
}
class MyRunnable implement Runnable{
@Override
public void run(){
// todo
}
}
Rufen Sie die Thread-Klasse direkt auf
public void onCreate(){
Thread thread = new Thread(MyRunnable());
}
class MyRunnable implement Runnable{
@Override
public void run(){
// todo
}
}
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Holen Sie sich die Start- und Stopp-Schaltflächenobjekte!
Button btn_start = findViewById(R.id.btn_start);
Button btn_stop = findViewById(R.id.btn_stop);
final Intent intent = new Intent(this,MyService.class);
btn_start.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
//Wenn MyService nicht gestartet ist, starten Sie es!
if(!MyService.serviceState) {
startForegroundService(intent);
}
}
});
btn_stop.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
// stopService()Also rufe ich onDestroy of MyService ~ an
stopService(intent);
}
});
}
MyService.java
public class MyService extends Service {
// serviceState =Wenn true, wurde MyService bereits gestartet
// threadState =Wenn true, wird Thread weiterhin ausgeführt
static boolean serviceState;
boolean threadState;
public MyService() {
serviceState = true;
threadState = true;
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
//Benachrichtigungsinhalt einrichten!
Notification notification;
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"id");
notification = builder.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("sanple")
.setContentText("text")
.build();
//Stellen Sie den Benachrichtigungskanal und die Wichtigkeit ein!
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel("id","name",importance);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
startForeground(1,notification);
//Starten Sie den Thread!
new Thread(new Runnable() {
@Override
public void run() {
int count = 0;
//Führen Sie das Zählprotokoll alle 2 Sekunden aus, während threadState true ist.
while(threadState){
Log.d("msg",String.valueOf(count));
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
}).start();
return START_NOT_STICKY;
}
@Override
public void onDestroy(){
Log.d("msg","onDestroy");
//StopService in MainActivity()Wenn Sie onDestroy anrufen()Wird genannt
//MyService wird gestoppt, Thread wird ebenfalls auf gestoppt gesetzt
serviceState = false;
threadState = false;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Die Thread-Zerstörung (stop ()) ist in API15 veraltet. Das heißt, schon vorher gab es einen Code-Bedarf, wie zum Beispiel den Wunsch, Thread zu zerstören oder ihn gewaltsam zu beenden, und ich empfahl auch Code, der zerstört werden kann. Es ist jedoch seit API15 veraltet. Dies liegt daran, dass das Verwerfen von Threads viel schlechten Müll hinterlässt.
Wenn Thread normal ausgeführt wird, können geschützte Objekte aufgrund des Verwerfens von Threads instabil werden, was zu unerwartetem Verhalten führen kann. Da es schwierig ist, Objekte zu finden oder zu identifizieren, die von Thread freigegeben wurden, sollten wir uns überlegen, ob Sie ein Programm mit Interrupt () entwerfen können, ohne Thread zu verwerfen, und über API 15 können Sie den Thread zwangsweise beenden. Es wurde veraltet. Verwenden Sie für niedliche niedliche Apps (und für Benutzer, die Ihre App lieben) Thread.stop () nicht, sondern codieren Sie das Design auf Interrupt () Weise!
Wenn du immer noch Stop () magst! Ist es also gut, es so zu verwenden, dass keine Personen (Objekte usw.) vermisst werden?
□ UI-Thread <-worker-Thread □ Worker-Thread <-Arbeiter-Thread
Handle ist eine Klasse, die zwischen Threads kommuniziert, und der Thread, der die Handle-Instanz erstellt hat, verfügt über die für die Kommunikation erforderlichen Funktionen von Queue und Looper. Von anderen Threads gesendete Informationen werden in einer Warteschlange gespeichert, und Looper ruft die gespeicherten Informationen ab und verarbeitet sie im Hauptthread (da sie im Hauptthread verarbeitet werden, ist es auch möglich, UI-Teile zu bedienen).
Es scheint, dass UI-Teile nicht direkt vom Worker-Thread aus bedient werden können. Verwenden Sie daher Methoden und Klassen zum Bedienen von UI-Teilen, um die Operationsverarbeitung von UI-Teilen an den UI-Thread zu übergeben.
Die Methode zum Bearbeiten von View mit View.post ist schwierig zu warten, da der Vorgang kompliziert wird </ font>. Es gibt auch eine Möglichkeit, Handle im Arbeitsthread zu verwenden, aber AsyncTask wird als Referenz empfohlen.
View.post () und View.postDelayed (), beides Methoden, die in View-Objekten gefunden werden. Post () aus verschiedenen Ansichten (TextView.post () oder Button.Post ()) wird auf der Seite der Empfangswarteschlange als dieselbe View.post () empfangen (identifizieren Sie den Absender als TextView oder EditText). Nicht).
public boolean post(Runnable action)
Klassenmethoden anzeigen: Wie TextView.post, TextEdit.post (), Button.post () können Ansichtsteile die Methoden post () und postDelayed () verwenden. post fügt Runnable zur Nachrichtenwarteschlange hinzu und verarbeitet Runnable im UI-Thread. Wenn der ausführbare Prozess erfolgreich ist, wird true zurückgegeben. Wenn false, scheint es viele Fälle zu geben, in denen die Nachrichtenwarteschlange beendet wurde.
activity_main.xml
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView"
/>
Verwenden der Thread-Klasse
public class MainActivity extends AppCompatActivity {
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
//Instantisieren und starten Sie die Thread-Klasse
ThreadSample threadSample = new ThreadSample();
threadSample.start();
}
}
class ThreadSample extends Thread{
public void run(){
//Bedienen Sie UI-Teile der Hauptaktivität
// post()Da die Methode Runnable als Argument verwendet, ist dies wie folgt
MainActivity.textView.post(new Runnable(){
@Override
public void run() {
MainActivity.textView.setText("From ThreadSample");
}
});
}
}
Zur Erinnerung, ich werde es auch in der anonymen Klasse schreiben.
python
public class MainActivity extends AppCompatActivity {
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
textView.post(new Runnable() {
@Override
public void run() {
textView.setText("From Another Thread");
}
});
}
}).start();
}
}
public boolean postDelayed(Runnable action,long delayMillis) Verzögerung ... Verzögerung; Millis ... Millisekunde </ font> postDelayed fügt Runnable zur Nachrichtenwarteschlange hinzu und verarbeitet nach einer bestimmten Zeit die Runnable im UI-Thread.
Wenn Sie den folgenden Code ausführen, wird die Textansicht mit dem Anfangswert "Hello World!" Begrüßt. Nach 5 Sekunden ändert sich die Anzeige jedoch in "From ThreadSample".
activity_main.xml
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView"
/>
In der Thread-Klasse
public class MainActivity extends AppCompatActivity {
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
ThreadSample threadSample = new ThreadSample();
threadSample.start();
}
}
class ThreadSample extends Thread{
public void run(){
MainActivity.textView.postDelayed(new Runnable(){
@Override
public void run() {
MainActivity.textView.setText("From ThreadSample");
}
},5000);
}
}
public final void runOnUiThread(Runnable action)
Aktivitätsklassenmethode: ** Aktivität kann runOnUiThread () ** verwenden. Aktivität bietet den UI-Bildschirm.
runOnUiThread führt die angegebene Aktion im UI-Thread aus. Wenn der aktuelle Thread ein UI-Thread ist, erfolgt die Aktion sofort! Andernfalls wird die Aktion zur Ereigniswarteschlange des UI-Threads hinzugefügt. Es scheint, dass das Verhalten fast genauso funktioniert wie die post () -Methode! ..
public class MainActivity extends AppCompatActivity {
public static TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable(){
@Override
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("runOnUiThread");
}
});
}
}).start();
}
}
■Handler Weitere Informationen finden Sie hier "Hanler Summary" Mit dem Handler können Sie ausführbare Objekte senden und Nachrichten verarbeiten, die der Nachrichtenwarteschlange eines Threads zugeordnet sind. Eine Instanz von Handler ist einem einzelnen Thread und einer Nachrichtenwarteschlange zugeordnet. Gibt true zurück, wenn es zur Nachrichtenwarteschlange hinzugefügt wird. Es ist nicht so, ob der Prozess erfolgreich war. Wenn der Looper vor Ablauf der angegebenen Zeit beendet wird, wird Runnable abgebrochen. Wenn falsch, vermuten Sie, dass die Nachrichtenwarteschlange beendet wurde!
■android.os.AsyncTask public abstract class AsyncTask extends Object android.os.AsyncTask<Params,Progress,Result>
Zusammenfassung hier Referenzcode hier
AsyncTask ist ein asynchroner Prozess. Besonders geeignet für die kurzzeitige asynchrone Verarbeitung. ** Bitte verwenden Sie andere APIs (Executor, ThreadPoolExecutor usw.) ** für die Verarbeitung, die lange läuft!