Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 循环器、处理程序和线程_Java_Android_Multithreading - Fatal编程技术网

Java 循环器、处理程序和线程

Java 循环器、处理程序和线程,java,android,multithreading,Java,Android,Multithreading,我希望将一个字节数组从应用程序的主线程(MainActivity)传递到“工作线程”,这样我就可以在工作线程中做任何我想做的事情,而不会阻塞UI(主线程)。 所以我读了关于Looper和Handler的文章,但我不理解,因为我读到我在处理程序中编写的所有内容都是在主线程中完成的,但我只想将参数/数据从主线程传递到另一个线程。 有人能给我举个例子吗?处理程序处理从循环器发送的消息和可运行对象。默认情况下,新创建的线程没有活套,因为它们通常是为了执行特定任务而创建的。如果希望一个线程驻留并处理来自其

我希望将一个字节数组从应用程序的主线程(MainActivity)传递到“工作线程”,这样我就可以在工作线程中做任何我想做的事情,而不会阻塞UI(主线程)。 所以我读了关于Looper和Handler的文章,但我不理解,因为我读到我在处理程序中编写的所有内容都是在主线程中完成的,但我只想将参数/数据从主线程传递到另一个线程。
有人能给我举个例子吗?

处理程序处理从循环器发送的消息和可运行对象。默认情况下,新创建的线程没有活套,因为它们通常是为了执行特定任务而创建的。如果希望一个线程驻留并处理来自其他线程的消息,那么可以为该线程创建一个循环器,并创建一个使用该循环器的处理程序

这是一个非常简单的示例,可能还有其他方法:

public class TestActivity extends AppCompatActivity {

TestThread thread;


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

    thread = new TestThread();
    thread.start();
}



public void testClick(View view) {
    // Check that handler object is assigned, as handler is initialised by the thread
    // itself after it has started running
    if(thread.handler != null) thread.handler.sendMessage(thread.handler.obtainMessage(123, new byte[12]));
}



private class TestThread extends Thread {

    Handler handler;


    @Override
    @SuppressLint("HandlerLeak")
    public void run() {
        // Creates the Looper object for this thread
        Looper.prepare();

        // Default Handler constructor uses the Looper of the current thread (the Looper we just created)
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // Handle message here, running within the thread
                if((msg.what == 123) && (msg.obj != null) && (msg.obj instanceof byte[]))
                    Log.d("Test", Integer.toString(((byte[])msg.obj).length) + " byte(s) received");
            }
        };

        // Does the work of actually looping and processing messages. This will
        // not return until the thread is being terminated
        Looper.loop();
    }

}
活动内容如下:

<?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=".TestActivity">
<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:onClick="testClick"
    android:text="Test"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
总之,处理程序在运行特定循环器的线程内执行。因此,如果您向使用主UI线程的循环器的处理程序发送消息,那么代码将在主UI线程中执行。如果您将消息发送给一个处理程序,该处理程序有自己的在不同线程中运行的循环器,那么它将在该特定线程中运行

[编辑]嗯。回过头来看,我的答案还不完全清楚,所以让我解释一下示例中发生了什么:这里,onCreate()方法在UI线程中运行,并创建另一个线程(我们称之为Thread2)。然后它启动Thread2,Thread2创建一个Looper和处理程序,然后位于一个无限循环中,通过调用Looper.loop()处理它接收到的消息


单击测试按钮时,会向Thread2处理程序发送一条消息。Thread2什么也不做,只是坐在那里等待消息,它注意到新消息并将其传递给处理程序,该处理程序调用重写的handleMessage()方法,该方法写入日志。然后,Thread2使用
Looper
恢复等待消息的任务,而
Handler
的级别非常低。大多数开发人员使用更高级别的解决方案会得到更好的服务:
AsyncTask
、RxJava、
LiveData
JobIntentService
,等等@commonware它们是低级的,但也是您列出的最简单的解决方案。有时候,在进入复杂的框架之前,最好先掌握简单而有效的东西,这些框架是建立在这些简单的东西之上的;thread.start();应该像线一样;线程=新线程(newtestthread());thread.start();但是,我无法访问新线程的处理程序……对不起,我不明白你在这里想说什么。示例代码清楚地创建了一个新线程,new关键字和它扩展了thread类的事实表明了这一点。如果您无法访问处理程序,那么可能意味着您的特定线程类不是内部类,在这种情况下,您可以将public关键字添加到处理程序字段declarationOK,我现在明白您的意思了。建议的代码创建两个对象,将TestThread作为可运行对象传递给另一个Thread对象。您不需要这样做,因为您可以直接扩展线程并保存额外的对象。无法访问处理程序字段,因为它属于TestThread类,而不是Thread类。按照我写的方式使用代码。我向你保证它是有效的,我在发布之前测试过它
Handler handler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        // Process message within main UI thread
    }
};