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
Android 运行其他线程不允许显示活动_Android_Multithreading_Android Layout_Android Activity_Java.util.concurrent - Fatal编程技术网

Android 运行其他线程不允许显示活动

Android 运行其他线程不允许显示活动,android,multithreading,android-layout,android-activity,java.util.concurrent,Android,Multithreading,Android Layout,Android Activity,Java.util.concurrent,我有一项活动: public class ResultActivity extends AppCompatActivity implements ResultListener { private String code = ""; private String data = ""; @Override protected void onCreate(Bundle savedInstanceState) {

我有一项活动:

public class ResultActivity extends AppCompatActivity implements ResultListener {
    private String code = "";
    private String data = "";

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

            code = intent.getStringExtra("code");
            data = intent.getStringExtra("data");

            MyExternal.DecodeAndSend(this, code, data);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
其中,
MyExternal
是其他库中的一个类

方法
DecodeAndSend
如下所示:

public static boolean DecodeAndSend(ResultListener caller, String codigo, String data)
{
    try {
        ExecutorService pool = Executors.newFixedThreadPool(1);

        HashMap<String,String> arguments = new HashMap<>();

        Future<String> resultado = pool.submit(new ServerConnection(caller, url, arguments));

        String status = resultado.get();
        if (status.equals("OK"))
            caller.OnSuccess();
        else
            caller.OnError(status);

        pool.shutdown();

        return true;
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

    return false;
}
调用
Thread.sleep(2000)
实际上是对web服务器的调用,以发送一些数据

问题是,
ResultActivity
调用返回之前不会显示其布局

此代码中缺少什么?

Future.get()
是一个-执行将停止,直到结果到达

只有在计算完成后,才能使用方法get检索结果,如有必要,请阻塞,直到它准备就绪

因此,您的
活动
onCreate
方法调用该内容,然后阻塞,直到
调用
(在另一个线程上运行)返回其结果。因此,
onCreate
没有完成,布局也没有完成

如果您想使用该阻塞代码,但在视图布局之后,我会使用另一部分,如
onStart
(设置一个标志,以便只运行一次!)。否则,您将需要使用其他一些并发技术来获得结果并使用它。这取决于您对
调用的结果实际执行的操作。get()
是一个-执行将停止,直到结果到达

只有在计算完成后,才能使用方法get检索结果,如有必要,请阻塞,直到它准备就绪

因此,您的
活动
onCreate
方法调用该内容,然后阻塞,直到
调用
(在另一个线程上运行)返回其结果。因此,
onCreate
没有完成,布局也没有完成


如果您想使用该阻塞代码,但在视图布局之后,我会使用另一部分,如
onStart
(设置一个标志,以便只运行一次!)。否则,您将需要使用其他一些并发技术来获得结果并使用它。这取决于您对
调用
函数

功能的结果实际执行的操作。get()
是一个阻塞调用。UI线程在等待调用返回时被阻塞,因此无法绘制布局。尝试将结果侦听器传递到
ResultListener
ServerConnection
,并使用这两个回调相应地更新UI

功能。get()
是一个阻塞调用。UI线程在等待调用返回时被阻塞,因此无法绘制布局。尝试将结果侦听器传递到
ResultListener
ServerConnection
,并使用这两个回调相应地更新您的UI

DecodeAndSend
从主线程调用。它调用
Future.get()
,等待作业完成,因此它阻塞了主线程。您也应该从后台线程调用此方法。我认为可以将它发送到同一个线程池,因为它是在等待的第一个作业之后提交的

您不能从这个方法返回任何关于请求结果的信息,因为它是异步的

public static void DecodeAndSend(ResultListener caller, String codigo, String data)
{
    ExecutorService pool = Executors.newFixedThreadPool(1);

    HashMap<String,String> arguments = new HashMap<>();

    Future<String> resultado = pool.submit(new ServerConnection(caller, url, arguments));

    pool.submit(new Runnable() {
        public void run () {
            try {
                String status = resultado.get();
                if (status.equals("OK"))
                    caller.OnSuccess();
                else
                    caller.OnError(status);

                pool.shutdown();
                return;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            caller.OnError(null); // No status, only an exception
    });
}
publicstaticvoiddecodeandsend(ResultListener调用者、字符串codigo、字符串数据)
{
ExecutorService池=Executors.newFixedThreadPool(1);
HashMap参数=新的HashMap();
Future resultado=pool.submit(新服务器连接(调用者、url、参数));
pool.submit(新的Runnable(){
公开作废运行(){
试一试{
字符串状态=resultado.get();
如果(状态等于(“正常”))
caller.OnSuccess();
其他的
调用方。OnError(状态);
pool.shutdown();
返回;
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}捕获(执行例外){
e、 printStackTrace();
}
caller.OnError(null);//没有状态,只有异常
});
}
但是,您的
ServerConnection
类已经接受了
caller
参数,因此它可能只处理回调本身。根据您在回调中的操作,您可能希望将回调调用发布到主线程


顺便说一句,Java中的惯例是总是以小写字母(驼峰大小写)开头方法名。

DecodeAndSend
是从主线程调用的。它调用
Future.get()
等待作业完成,因此它会阻塞主线程。您也应该从后台线程调用此方法。我认为可以将其发送到同一线程池,因为它是在等待的第一个作业之后提交的

您不能从这个方法返回任何关于请求结果的信息,因为它是异步的

public static void DecodeAndSend(ResultListener caller, String codigo, String data)
{
    ExecutorService pool = Executors.newFixedThreadPool(1);

    HashMap<String,String> arguments = new HashMap<>();

    Future<String> resultado = pool.submit(new ServerConnection(caller, url, arguments));

    pool.submit(new Runnable() {
        public void run () {
            try {
                String status = resultado.get();
                if (status.equals("OK"))
                    caller.OnSuccess();
                else
                    caller.OnError(status);

                pool.shutdown();
                return;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            caller.OnError(null); // No status, only an exception
    });
}
publicstaticvoiddecodeandsend(ResultListener调用者、字符串codigo、字符串数据)
{
ExecutorService池=Executors.newFixedThreadPool(1);
HashMap参数=新的HashMap();
Future resultado=pool.submit(新服务器连接(调用者、url、参数));
pool.submit(新的Runnable(){
公开作废运行(){
试一试{
字符串状态=resultado.get();
如果(状态等于(“正常”))
caller.OnSuccess();
其他的
调用方。OnError(状态);
pool.shutdown();
返回;
}捕获(IOE异常){
e、 printStackTrace();
}捕捉(中断异常e){
e、 printStackTrace();
}捕获(执行例外){
e、 printStackTrace();
}
caller.OnError(null);//没有状态,只有异常
});
}