Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.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 Android线程、处理程序、handleMessage:从外部类文件中的可运行线程更新UI线程_Java_Android_Multithreading_Handler_Ui Thread - Fatal编程技术网

Java Android线程、处理程序、handleMessage:从外部类文件中的可运行线程更新UI线程

Java Android线程、处理程序、handleMessage:从外部类文件中的可运行线程更新UI线程,java,android,multithreading,handler,ui-thread,Java,Android,Multithreading,Handler,Ui Thread,背景: 我正在尝试将Java(非GUI)程序转换为在Android上运行。为简单起见,假设此程序具有以下文件: DSGen.java、SInfer.java、Main.java 在Main()方法中,初始化每个类DSGen和SInfer的对象,并将其传递到新线程中并启动。另外,每个类DSGen和SInfer都使用一个公共void run()方法实现Runnable,并且两个run方法都将文本输出到system.out.println() 线程1。生成100个随机数据值 线程2。对生成数据的100

背景: 我正在尝试将Java(非GUI)程序转换为在Android上运行。为简单起见,假设此程序具有以下文件:

DSGen.java、SInfer.java、Main.java

在Main()方法中,初始化每个类DSGen和SInfer的对象,并将其传递到新线程中并启动。另外,每个类DSGen和SInfer都使用一个公共void run()方法实现Runnable,并且两个run方法都将文本输出到system.out.println()

线程1。生成100个随机数据值 线程2。对生成数据的100个值进行计算(输出100个结果)

在Android版本的程序中,我知道UI线程处理所有UI更新。 因此,在MainActivity.java文件中,我试图声明一个处理程序来接收来自“线程2和输出数据”的消息,该消息可用于更新MainActivity UI线程中的TextView。当我按下Android UI上的开始按钮时,应用程序开始执行

问题: 运行此应用程序时,直到处理结束,我的TextView才会更新。我还注意到,并不是所有的输出都会更新到我的TextView,只有40/100的计算会真正更新到TextView

程序的实际代码相当长,我认为最好只包含与SInfer类的线程、处理程序和run方法相关的部分

我希望有人能给我一个伪代码示例或解决方案,用于处理多个线程,其中可运行方法在两个不同的类文件(而不是MainActivity中的内部类)中声明,并且可以通过将一条消息从一个线程传递回UI线程来更新UI

提前谢谢你

public class MainActivity extends Activity {

    /* UI Elements */
    private TextView output;

    /* Thread Handler */
    private Handler uiHandler;

    /* Handle message override */
    public class UIHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            output.append(msg.obj.toString());
            super.handleMessage(msg);
        }
    }

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

        output = (TextView) findViewById(R.id.displayTextView);
        uiHandler = new UIHandler();

        setStartButtonClickListener();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_run_fsi, menu);
        return true;
    }


    private void setStartButtonClickListener() {
        Button startButton = (Button) findViewById(R.id.startButton);
        startButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                runFSI();

            }
        });
    }

    private void runFSI() {
        // initialize SInfer and pass uiHandler

        SInfer inferer = SInfer.getInstance(/*other variables*/, uiHandler);


        // initialize DSGen
        DSGenerator dsGen;

        Thread t1 = new Thread(dsGen);
        Thread t2 = new Thread(inferer);
        t1.start();
        t1.yield();
        t2.start();
        t2.yield();

        try {
            Thread.sleep(10000);
        } catch (Exception e) {
        }

        inferer.stop();
        dsGen.stop();

    }

}
SInfer中定义的run方法如下(system.out代码是原始Java代码的遗留代码)


你正在运行线程。睡眠(10000);在主线程中(在UI线程中调用OnClick),因此在这10秒内UI中无法更新任何内容。 尝试在单独的线程中调用您的runFSI方法。

使用

重写doInBackground()以处理所有背景计算

重写onProgressUpdate()以在UI线程使用publishProgress()方法运行时与该线程进行对话


并重写onPostExecute(),以在UI线程上执行任何最后的操作。

感谢您指出这一点。在更新TextView之前,睡眠肯定会延迟10秒!正如建议的那样,如果我为FSI创建单独的线程(称为线程0),这反过来又会创建两个以上的线程。其中,线程2依赖于线程1生成的数据。最好的办法是什么?为FSI创建一个内部类?另外,我是否只传递一个对uiHandler的引用,该引用可以依次传递到线程2中,以便将结果作为消息发送?再次感谢!
@Override
public void run() {

    // System.out.println("Inference: Thread started...");

    while (stopFlag == false) {
        try {
            // System.out.println("SInference: run.........");
            Thread.sleep(200);
            inferenceResult = doInference();

            /* Send result to UI thread */

            Message msg = Message.obtain(uiHandler);
            msg.obj = inferenceResult.toString();
            uiHandler.sendMessage(msg);

        } catch (InterruptedException e) {
            // System.out.println(e.getMessage());
        }
    }
}