2017-09-16 71 views
2

我有Android應用的一個例子來更新使用處理器工作線程主線程進度,它的正常工作,但是當我嘗試內更新進度工作者線程沒有處理程序,它仍然有效,儘管它應該會崩潰。因爲根據Android文檔,UI線程不安全,不能直接從工作線程訪問。從工作線程主線程有時更新進度條不崩潰的Android應用程序

***更新 對不起,我把錯誤activity_main.xml中。 這是我正在使用的正確的一個。

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.riaz.handlerexample.MainActivity"> 

    <ProgressBar 
     android:id="@+id/progressBar" 
     style="?android:attr/progressBarStyleHorizontal" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="8dp" 
     android:layout_marginLeft="8dp" 
     android:layout_marginRight="8dp" 
     android:layout_marginTop="8dp" 
     app:layout_constraintBottom_toBottomOf="parent" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintTop_toTopOf="parent" 
     android:indeterminate="false" 
     android:max="100" 
     android:progress="0" 
     android:layout_marginStart="8dp" 
     android:layout_marginEnd="8dp" /> 
</android.support.constraint.ConstraintLayout> 

***更新

這裏是activity_main.xml中。 **更新。錯佈局文件,請忽略Question

如今

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<ProgressBar 
    android:id="@+id/progressBar1" 
    style="?android:attr/progressBarStyleHorizontal" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:indeterminate="true" 
    android:max="10" 
    android:padding="4dip" > 
</ProgressBar> 

    <TextView 
     android:id="@+id/tv" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="Progress percentage" 
     android:textSize="16sp"/> 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:onClick="startProgress" 
     android:text="Start" 
     android:textSize="16sp"/> 

</LinearLayout> 

Java代碼

import android.os.Handler; 
import android.os.Message; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.widget.ProgressBar; 
import android.widget.Toast; 


public class MainActivity extends AppCompatActivity { 

     Thread thread; // work as a background thread 
     Handler handler; // handle main thread messages from worker thread 
     ProgressBar progressBar; // on UI/main thread 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


     progressBar = (ProgressBar) findViewById(R.id.progressBar); 


     Toast.makeText(MainActivity.this, "OnCreate Thread Name = " 
         +Thread.currentThread().getName(), 
       Toast.LENGTH_LONG).show(); // Thread Name = main 

     System.out.println("OnCreate Method,Thread Name= " + 
       Thread.currentThread().getName()); // Thread Name = main 


     thread = new Thread(new MyThread());// creating a background thread 
     thread.start(); // starting the background thread. it will execute run() method in 
         // MyThread class 

     handler = new Handler(){ //handles the incoming messages from background thread 

      @Override // receives message from worker thread sendmessage(message) 
      public void handleMessage(Message msg) { 

       System.out.println("Inside Handler,Thread Name= " + 
         Thread.currentThread().getName()); //thread Name = main 

       // progressBar.setProgress(msg.arg1); 
      } 
     }; 


    } 


    // this is background/worker thread 

    class MyThread implements Runnable 
    { 
     @Override 
     public void run() { 

      Toast.makeText(MainActivity.this, "Worker Thread Name = " 
          +Thread.currentThread().getName(), 
        Toast.LENGTH_LONG).show(); // Thread Name = main 

      for (int i=0; i<100;i++) 
      { 

       System.out.println("Worker Thread,Thread Name= " + 
         Thread.currentThread().getName()); 

       // Message message = Message.obtain(); // blank empty message 
       // message.arg1 = i; 
       // handler.sendMessage(message); //calling main thread 

       progressBar.setProgress(i); 


       //create delay to see the progress on progressbar 

       try { 
        Thread.sleep(300); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+1

兄弟公司崩潰'了java.lang.RuntimeException:無法內螺紋創建處理程序尚未調用Looper.prepare()' – akhilesh0707

+1

您從main.xml中初始化'progressBar'但在主XML內部,它是'progressBar1' – akhilesh0707

+0

@ akhilesh0707是的,你是對的,有時它崩潰,有些時候沒有。一旦它崩潰,編輯代碼後繼續崩潰,但一旦我重新啓動android studio和模擬器​​並再次運行它,那麼它工作正常,並繼續工作正常,除非我更改代碼並重新啓動android工作室和模擬器。 –

回答

2

作爲CommonsWare答案,ProgressBar有邏輯,允許setProgress()在後臺線程中調用。它會檢查您正在使用的線程,並根據需要自行執行Runnablepost()

回答參考link