有时,从工作线程更新主线程上的进度条不会';不要让android应用程序崩溃

有时,从工作线程更新主线程上的进度条不会';不要让android应用程序崩溃,android,multithreading,Android,Multithreading,我有一个android应用程序的例子,它使用处理程序从工作线程更新主线程上的progressbar,它工作得很好,但是当我尝试在没有处理程序的工作线程内更新progressbar时,它仍然工作,尽管它应该崩溃。因为根据Android文档,UI线程是不安全的,不能直接从工作线程访问 ***更新 抱歉,我放错了activity_main.xml。 这是我正在使用的正确的一个 <?xml version="1.0" encoding="utf-8"?> <android.suppor

我有一个android应用程序的例子,它使用处理程序从工作线程更新主线程上的progressbar,它工作得很好,但是当我尝试在没有处理程序的工作线程内更新progressbar时,它仍然工作,尽管它应该崩溃。因为根据Android文档,UI线程是不安全的,不能直接从工作线程访问

***更新 抱歉,我放错了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>

***更新

以下是活动_main.xml。**更新。布局文件错误,请忽略

<?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();
                }
            }
        }
    }
}
导入android.os.Handler;
导入android.os.Message;
导入android.support.v7.app.AppActivity;
导入android.os.Bundle;
导入android.widget.ProgressBar;
导入android.widget.Toast;
公共类MainActivity扩展了AppCompatActivity{
Thread Thread;//用作后台线程
Handler;//处理来自工作线程的主线程消息
ProgressBar ProgressBar;//在UI/主线程上
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar=(progressBar)findViewById(R.id.progressBar);
Toast.makeText(MainActivity.this,“OnCreate线程名称=”
+Thread.currentThread().getName(),
Toast.LENGTH_LONG).show();//Thread Name=main
System.out.println(“OnCreate方法,线程名称=”+
Thread.currentThread().getName());//Thread Name=main
线程=新线程(new MyThread());//创建后台线程
thread.start();//启动后台线程。它将在中执行run()方法
//神话阅读课
handler=newhandler(){//处理来自后台线程的传入消息
@重写//从工作线程接收消息sendmessage(消息)
公共无效handleMessage(消息消息消息){
System.out.println(“内部处理程序,线程名称=”+
Thread.currentThread().getName());//Thread Name=main
//progressBar.setProgress(msg.arg1);
}
};
}
//这是后台/工作线程
类MyThread实现可运行
{
@凌驾
公开募捐{
Toast.makeText(MainActivity.this,“工作线程名称=”
+Thread.currentThread().getName(),
Toast.LENGTH_LONG).show();//Thread Name=main
对于(int i=0;i作为

现在,
ProgressBar
具有允许在后台线程上调用
setProgress()


Answer reference

brother its crasted
java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
您正在从main.xml初始化
progressBar
,但在main.xml中它是
progressBar1
@akhilesh0707是的,您是对的,有时它会崩溃,有时不会。一旦崩溃,它在编辑代码后会继续崩溃,但一旦我重新启动android studio和emulator并再次运行它,它就会正常运行请继续正常工作,除非我更改代码并重新启动android studio和emulator。@akhilesh0707如果你是对的,我粘贴了错误的布局xml文件。请查看正确的更新xml文件。禁用“即时运行”并重试,每次都会崩溃