当另一个线程正在工作时,活动在启动时冻结

Posted

技术标签:

【中文标题】当另一个线程正在工作时,活动在启动时冻结【英文标题】:Activity freezing on startup while another thread is doing work 【发布时间】:2019-09-24 16:55:21 【问题描述】:

编辑:正如 Mike M. 和 Vladyslav Matviienko 和 Vivek Mishra 指出的那样

new Runnable().run(); 

不是一个单独的线程。谢谢各位:)

编辑结束。

当我启动一个使用单独线程与服务器通信的新 Activity 时,它会冻结。

我用

开始一个新的活动
Intent i = new Intent(this, AcmActivity.class);
startActivityForResult(i, acm_ui);

然后我在onCreate() 中对我的客户端类运行异步调用

protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.acm);

        //get the client implementation
        ClientImpl client = ServiceManager.getService(ClientImpl.class);
        client.getData(new PrivateClientCallback())


private class PrivateClientCallback implements GeneralCallback 
        @Override
        public void ok(final String response) 
            runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    updateSomeView(response);
                
            );
        

ClientImpl.getData() 看起来像这样:

public synchronized void getData(GeneralCallback cb) 
        new Runnable() 
            @Override
            public void run() 
                //allow networking within this Thread
                //read more here: https://***.com/questions/25093546/android-os-networkonmainthreadexception-at-android-os-strictmodeandroidblockgua
                if (android.os.Build.VERSION.SDK_INT > 9) 
                    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                    StrictMode.setThreadPolicy(policy);
                

                //send some stuff to server and use the Callback
                String stuff = someStuff();
                cb.ok(stuff);
            .run();


不幸的是,我的 Activity 冻结,直到来自服务器的调用返回。

我希望 Activity 启动并且当服务器响应更新其视图时,不幸的是这不是发生的情况。我不知道为什么。

【问题讨论】:

这不是一个单独的线程。你只是在当前线程上运行新的Runnable 那不是一个线程,那只是一个可运行的,你在创建后立即在主线程上运行。 Runnable.run() 只是在当前线程上调用run() 方法。 【参考方案1】:

new Runnable() 只是一个普通对象。您需要创建一个带有可运行对象的新线程。然后它将在单独的线程上运行。

检查下面的代码

public synchronized void getData(GeneralCallback cb) 
        new Thread(new Runnable() 
            @Override
            public void run() 
                //allow networking within this Thread
                //read more here: https://***.com/questions/25093546/android-os-networkonmainthreadexception-at-android-os-strictmodeandroidblockgua
                if (android.os.Build.VERSION.SDK_INT > 9) 
                    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                    StrictMode.setThreadPolicy(policy);
                

                //send some stuff to server and use the Callback
                String stuff = someStuff();
                cb.ok(stuff);
            ).start(); 

【讨论】:

以上是关于当另一个线程正在工作时,活动在启动时冻结的主要内容,如果未能解决你的问题,请参考以下文章

在 onStop() 之后,带有线程的 Android 活动被破坏

当一个线程遇到异常时是不是可以冻结所有线程

当另一个工作簿处于活动状态时,UDF 引用命名表错误

当主线程显然未阻塞时,QProgressDialog 冻结

Android 应用程序在完成活动时冻结,runOnUiThread() 停止工作

QT QThread::isrunning 冻结程序在 Pi