Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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/8/variables/2.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
Android 为什么Handler::postDelay使UI冻结_Android_Multithreading - Fatal编程技术网

Android 为什么Handler::postDelay使UI冻结

Android 为什么Handler::postDelay使UI冻结,android,multithreading,Android,Multithreading,我有这个密码。我不知道为什么在这种情况下postDelay会使UI冻结。我希望Runnable将在100毫秒后运行,deley将在4000毫秒后运行 package com.delaythread; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android

我有这个密码。我不知道为什么在这种情况下postDelay会使UI冻结。我希望Runnable将在100毫秒后运行,deley将在4000毫秒后运行

package com.delaythread;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;

public class MyNeedActivity extends Activity implements OnClickListener {

    private ProgressBar progressBar;
    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(final Message msg) {
            super.handleMessage(msg);
            progressBar.setVisibility(ProgressBar.INVISIBLE);
        }
    };

    @Override
    public void onClick(final View v) {
        if(v.getId() == R.id.button1) {
            /* This call doesn't make ProgressBar frozen.
            final Thread t = new Thread(new MyRunnable());
            t.start();
            progressBar.setVisibility(ProgressBar.VISIBLE);
             */

            // This makes ProgressBar frozen in 4000 miliseconds.
            final boolean b = handler.postDelayed(new MyRunnable(), 100);
            if(b) {
                progressBar.setVisibility(ProgressBar.VISIBLE);
            }
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ((Button)findViewById(R.id.button1)).setOnClickListener(this);
        progressBar = (ProgressBar)findViewById(R.id.progressBar1);
    }

    private class MyRunnable implements Runnable {
        @Override
        public void run() {
            sleep();
        }

        private void sleep() {
            try {
                Thread.sleep(4000);
                handler.sendEmptyMessage(0);
            } catch (final InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

更新:实际上我想要的是AsyncTask在一段延迟时间后执行,所以我按照这个答案执行。他说我应该使用Handler和Runnable。

据我所知,你要求你的
MyRunnable
在GUI线程(只有一个)上运行;但它唯一能做的就是睡眠,这会导致GUI线程冻结等待它

您不应该在GUI线程中执行复杂的计算(或睡眠)


您可能需要阅读更详细的描述。

据我所知,您要求您的
MyRunnable
在GUI线程(只有一个)上运行;但它唯一能做的就是睡眠,这会导致GUI线程冻结等待它

您不应该在GUI线程中执行复杂的计算(或睡眠)


您可能需要阅读更详细的描述。

您可能希望在主UI线程以外的其他线程上运行
MyRunnable
,因此需要为此启动一个常规线程,如

new Thread(new MyRunnable()).start();
而不是为此使用
处理程序
,它将您的runnable排队,以便在主UI线程上执行


顺便说一句,出于此目的,使用将更合适。

您可能希望在主UI线程以外的其他线程上运行您的
MyRunnable
,因此需要为此启动一个常规线程,如

new Thread(new MyRunnable()).start();
而不是为此使用
处理程序
,它将您的runnable排队,以便在主UI线程上执行


顺便说一句,出于此目的,使用将更合适。

您的进度条没有更新,因为您没有更新它!尝试使用(它在不同的线程上运行,但允许您更新UI元素)并在异步任务的onProgress方法中设置进度条的状态


只需在Android上执行此示例,您的进度条不会更新,因为您没有更新它!尝试使用(它在不同的线程上运行,但允许您更新UI元素)并在异步任务的onProgress方法中设置进度条的状态


只需在Android上执行此示例即可

类处理程序的Android参考指出:

[…]创建新处理程序时,它将绑定到创建它的线程的线程/消息队列[…]

因此,在活动实例化时创建的处理程序应该在UI线程上运行,从而在执行Runnable时阻塞它

尝试创建一个新的线程类,在其中实例化处理程序。然后将Runnable从onClick()方法传递给它。要传回消息(例如更新进度条),可以使用UI线程上运行的另一个处理程序

你也可以通过看一看课堂来避免很多痛苦

附言:
可以通过Thread.sleep(100)调用在AsyncTaskdoInBackground()中延迟执行。要延迟UI线程级别的执行,可以在AsyncTask.onPreExecute()中执行相同的操作。

类处理程序的Android参考指出:

[…]创建新处理程序时,它将绑定到创建它的线程的线程/消息队列[…]

因此,在活动实例化时创建的处理程序应该在UI线程上运行,从而在执行Runnable时阻塞它

尝试创建一个新的线程类,在其中实例化处理程序。然后将Runnable从onClick()方法传递给它。要传回消息(例如更新进度条),可以使用UI线程上运行的另一个处理程序

你也可以通过看一看课堂来避免很多痛苦

附言:
可以通过Thread.sleep(100)调用在AsyncTaskdoInBackground()中延迟执行。要延迟UI线程级别上的执行,您可以在AsyncTask.onPreExecute()中执行相同的操作。

根据文章,以下内容应该适合您的需要

private final Handler handler = new Handler() {
    @Override
    public void handleMessage(final Message msg) {
        super.handleMessage(msg);
        //start Asyntask here. progress show/hide should be done in asynctaswk itself.
    }
};

@Override
public void onClick(final View v) {
    if(v.getId() == R.id.button1) {

        final boolean b = handler.postDelayed(new MyRunnable() , 1000);

    }
}

private class MyRunnable implements Runnable {
    @Override
    public void run() {
        handler.sendmessage(0);
    }
}

}

根据职位要求,以下内容应适合您的需要

private final Handler handler = new Handler() {
    @Override
    public void handleMessage(final Message msg) {
        super.handleMessage(msg);
        //start Asyntask here. progress show/hide should be done in asynctaswk itself.
    }
};

@Override
public void onClick(final View v) {
    if(v.getId() == R.id.button1) {

        final boolean b = handler.postDelayed(new MyRunnable() , 1000);

    }
}

private class MyRunnable implements Runnable {
    @Override
    public void run() {
        handler.sendmessage(0);
    }
}

}
试试这个:

new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    //Code to be executed after desired seconds
                }
            }, seconds*1000);
这将在给定的秒数内冻结UI,并在run()中执行代码。

尝试以下操作:

new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    //Code to be executed after desired seconds
                }
            }, seconds*1000);

这将在给定的秒数内冻结UI,并在run()中执行代码。

否,我希望Runnable在延迟时间后执行复杂的计算,而不是在UI线程中。这就是我创建Runnable的原因。@ernazm是对的,如果在Runnable中执行的操作与UI无关,那么使用处理程序可能不是最佳选择。不,我希望Runnable在延迟时间后执行复杂的计算,而不是在UI线程中。这就是我创建Runnable的原因。@ernazm是对的,如果在Runnable中执行的操作与UI无关,那么使用处理程序可能不是最佳选择。您能更详细地解释一下正在发生的事情和希望发生的事情吗?我希望Runnable进行长时间计算,但要经过一段延迟时间。所以我必须使用Handler::postDelay。Runnable计算时,ProgressBar可见。当它结束时,Runnable是不可见的。好吧,那到底发生了什么?实际上我想做一些类似于这个问题的事情。但是进度条冻结了(你想做什么?为什么在后台线程中需要延迟?你能更详细地解释一下发生了什么以及你想发生什么吗?我希望Runnable进行长时间的计算,但要经过一段延迟时间。因此我必须使用Handler::postDelay。Runnable计算时,ProgressBar可见。当它完成时,Runnable invisible.Ok,实际上发生了什么?实际上我想做一些类似于这个问题的事情。但是ProgressBar冻结了。:(你想做什么?为什么你需要在后台线程中进行延迟?如何在延迟时间后启动AsyncTask?这个问题的答案是: