使用严苛模式打破Android4.0以上平台应用中UI主线程的“独断专行”

dpkg: error processing package *** (--configure)错误解决办法 在 Ubuntu 执行sudo apt-get upgrade 或sudo apt-get install时,出现了如下的报错: dpkg: error processing package *** subprocess installed post-installation script returned error exit status 127 这主要是由于不完全安装导致的。解决方... 阅读详情

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229

        最近单位来了一个Android4.1平台的360街景项目。在编写该项目demo的过程中,为了省事,打算直接在UI线程中访问网络数据源并生成Bitmap以填充相应的视图。访问网络模块的封装采用了HttpClient的方式进行构建。编写完工后执行程序,发现视图显示的还是本地的默认图样。在确认了网络权限已被开启的情况下,我开始怀疑是不是HttpClient封装的粒度过大,导致其适用范围受限的问题。于是干脆采用Java平台最底层的Socket套接字方式来实现网络访问,可是结果还是一样的,仍旧无法得到网络数据。经过调试发现,在客户端发出请求之后,根本无法连接到服务端,也就无法解析后续的服务端的响应内容了。

        以前在Android2.3.3平台上研发怎么没有这个现象?难道是Android4.0的单线程模式的“禁令”较之以往更为严格了。为了使应用程序具有更好的交互性和更少的延迟时间,强势要求开发人员在UI主线程中只能执行与UI相关的工作(如:更新视图、与用户交互等),其他方面的工作一律禁止执行。为了验证这个相反,在stackoverflow.com检索了相关议题,从一位Google工程师的解答中基本得到了印证。也就是说,如果你非要在UI主线程中执行其他工作(如:访问网络、文件操作等),其实有这种编程强迫症的人在项目初期还是很多的,笔者就是其中的一位。你需要为UI主线程所在的Activity设置线程策略,告知平台请赋予我在UI主线程中进行其他工作的权限。具体做法有如下:

        在你的Application、Activity或其它应用容器中添加如下代码:

 public void onCreate() {
     if (DEVELOPER_MODE) {
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads() // 捕捉读取磁盘
                 .detectDiskWrites() // 捕捉写入磁盘
                 .detectNetwork()   // 捕捉网络访问 或使用detectAll() 火力全开
                 .penaltyLog() // 捕捉LogCat日志
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
     }
     super.onCreate();
 }

StrictMode类

        StrictMode是一个开发者工具类,从Android 2.3平台开始被引入。可以用于捕捉发生在应用程序UI主线程中耗时的IO操作、网络访问或方法调用;也可以用来改进应用程序,使得UI主线程在处理IO操作和访问网络时显得更平滑,避免其被阻塞,导致ANR警告。更多有关StrictMode的信息,请参见http://developer.android.com/reference/android/os/StrictMode.html。

        这种非常规的做法,是在项目初期和开发模式下为了达到更高的效率,而采取一种提高生产效率做法。在产品交付和运维时,我们还是要严格遵守Android平台进程与线程安全管理机制。接下来是在实际开发中应该遵循的两个原则:

UI主线程

        在UI主线程中,只处理与UI相关及用户交互的工作,耗时的工作一律交由后台工作线程去搭理。常见的耗时工作处理方式有:

AsyncTask;

Handler、MessageQueue、Looper;

ExecutorService(execute/submit)

工作线程

        在工作线程中,只做自己分内的事。决不干涉UI主线程的工作。在执行过程中如果存在涉及到UI的操作(如:更新视图、重绘等),一律将其转交给UI主线程进行处理。常见的转交方式有:

Activity.runOnUiThread(new Runnable(){...});

View.post(new Runnable(){...});

View.postDelay(Runnable(){...},long)

示例

        最后,提供AsyncMultiThreadActivity演示Android多线程与UI交互的方式,仅供读者参考使用。

public class AsyncMultiThreadActivity extends Activity {  
   
    private TextView txView;  
    private Button button;  
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        Log.i("RootyInfo", "oncreate");  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);      
           
        txView=(TextView)findViewById(R.id.textView1);  
        button=(Button)findViewById(R.id.button1);  
        button.setOnClickListener(new OnClickListener() {  
               
            @Override 
            public void onClick(View v) {
                   
                //创建一个用于展示前三种后台线程和UI线程交互的线程  
                new TestThread(MainActivity.this).start();  
                   
                //创建一个用于展示AsyncTask实现交互的TestAsyncTask  
                new TestAsyncTask().execute("Test"," AsyncTask");  
            }  
        });  
    }  
       
       
    class TestAsyncTask extends AsyncTask<String, Integer, String> {  
        //TestAsyncTask被后台线程执行后,被UI线程被调用,一般用于初始化界面控件,如进度条  
        @Override 
        protected void onPreExecute() {  

            super.onPreExecute();  
        }  
   
        //doInBackground执行完后由UI线程调用,用于更新界面操作  
        @Override 
        protected void onPostExecute(String result) {  

            txView.setText(result);  
            super.onPostExecute(result);  
        }  
   
        //在PreExcute执行后被启动AysncTask的后台线程调用,将结果返回给UI线程  
        @Override 
        protected String doInBackground(String... params) {  

            StringBuffer sb=new StringBuffer();  
            for (String string : params) {  
                sb.append(string);  
            }  
            return sb.toString();  
        }  
           
    }
  
    //用于线程间通信的Handler  
    class TestHandler extends Handler {  
           
        public TestHandler(Looper looper) {  
            super(looper);  

        }  
   
        @Override 
        public void handleMessage(Message msg) {  

            System.out.println("123");  
            txView.setText((String)msg.getData().get("tag"));  
            super.handleMessage(msg);  
        }  
           
    } 
 
    //后台线程类  
    class TestThread extends Thread {  
        Activity activity;  
        public TestThread(Activity activity) {       
            this.activity = activity;  
        }  
        @Override 
        public void run() {  
               
            // 演示Activity.runOnUIThread(Runnable)方法的实现  
            activity.runOnUiThread(new Runnable() {               
                @Override 
                public void run() {  

                    txView.setText("Test runOnUIThread");  
                }  
            });  
               
            // 演示Activity.runOnUIThread(Runnable)方法的实现  
            txView.post(new Runnable() {  
                   
                @Override 
                public void run() {  

                    txView.setText("Test View.post(Runnable)");  
                }  
            });  
               
            // 演示Activity.runOnUIThread(Runnable)方法的实现  
            txView.postDelayed(new Runnable() {  
                   
                @Override 
                public void run() {  

                    txView.setText("Test View.postDelay(Runnable,long)");  
                }  
            }, 1000);  
               
            // 演示Handler方法的实现  
            Message msg=new Message();  
            Bundle bundle=new Bundle();  
            bundle.putString("tag", "Test Handler");  
            msg.setData(bundle);              
            new TestHandler(Looper.getMainLooper()).sendMessage(msg);  
                       
            super.run();  
        }  
           
    }  
      
}
E: Sub-process /usr/bin/dpkg returned an error code (1)解决办法 安装openssl-server出现了错误 阅读详情

相关推荐

ubuntu20.04安装openssh-server大量依赖错误的解决方法

Ubuntu安裝ssh依赖缺失的问题 pkgProblemResolver::Resolve generated breaks, this may be caoused by held pacages

weixin_45537232的博客 5177

dpkg: error processing package openssh-server (--configure) 处理办法

【代码】dpkg: error processing package openssh-server (--configure) 处理办法。

qq_30883899的博客 3967

dpkg:处理 xxx (--configure)时出错解决办法

   错误: dpkg: 处理软件包 initramfs-tools (--configure)时出错:  installed initramfs-tools package post-installation script subprocess returned error exit status 1 在处理时有错误发生:  initramfs-tools E: Sub-process /u...

鬼刀 9362

12.安装软件是报错:处理软件包 linux-image-4.4.1-040401-generic (--configure)时出错

处理软件包 linux-image-4.4.1-040401-generic (--configure)时出错参考:http://blog.youkuaiyun.com/u013022149/article/details/60744518第一步:备份$ sudo mv /var/lib/dpkg/info /var/lib/dpkg/info.bk第二步:新建$ sudo mkdir /var/lib/dp...

liuzhiqing666的博客 1631

dpkg:处理软件包 xxx (--configure)时出错

我的ubuntu是16.04版本,今天安装软件各种突然安装不上,有如下提示: /×××××××××××××××××××××××××× dpkg: 处理软件包 python-crypto (--configure)时出错:  子进程 已安装 post-installation 脚本 返回错误状态 1 ... dpkg: 处理软件包 samba-common-bin (--confi

gestoew的博客 2665

DOTween回调函数的隐藏技巧:优化你的Unity动画流程

本文深入探讨了DOTween回调函数在Unity动画开发中的高级应用技巧,帮助开发者优化动画流程。通过分析回调机制、链式应用模式和大规模动画系统管理,提升性能与可维护性,特别适合需要高效处理复杂动画场景的Unity开发者。

weixin_27945229的博客 319

dpkg 处理软件包 xxx (--configure)时出错 解决办法

dpkg: 处理软件包 xxx (–configure)时出错 解决办法 第一步:备份 $ sudo mv /var/lib/dpkg/info /var/lib/dpkg/info.bk 第二步:新建 $ sudo mkdir /var/lib/dpkg/info 第三步:更新 $ sudo apt-get update $ sudo apt-get -f instal...

zhengshibin博客 1681

告别手动!用Python+CATIA V5/V6自动生成三视图和标题栏(附完整代码)

本文详细介绍了如何利用Python和CATIA V5/V6实现工程图自动生成,包括三视图布局和标题栏填写。通过COM接口调用和智能算法,系统能自适应不同尺寸模型,大幅提升设计效率。附完整代码和部署方案,帮助团队实现从手动到自动化的转变。

weixin_42699679的博客 354

dpkg:处理软件包 xxx (-configure)时出错 解决办法

错误时间:安装kicad的时候 1.备份 $sudo mv /var/lib/dpkg/info/var/lib/dpkg/info.bk 2.新建 $sudo mkdir/var/lib/dpkg/info 3.更新 $sudo apt-get update 4.还原 $sudo mv /var/lib/dpkg/info.bk /var/lib/dpkg/in...

qq_41925676的博客 1216

ROS2 CANopen 使用教程

第一步是定义一个结构,用于保存有关接头和相关 CANopen 数据的信息。该结构是 CANopen 网络的基础,可确保存储所有相关数据并在需要时进行访问。

机器人控制与仿真应用 3691

OpenCASCADE:写IGES

OpenCASCADE:写IGES程序涵盖的领域流程说明初始化过程设置翻译参数执行 Open CASCADE Technology 形状转换编写 IGES 文件将开放级联技术形状映射到 IGES 实体曲线表面拓扑实体——人脸模式下的平移公差管理在 IGES 文件中设置分辨率代码架构调用图例子 程序 您可以通过以下步骤将 OCCT 形状转换为 IGES 实体: 初始化进程。 设置翻译参数, 执行模型翻译, 写入输出 IGES 文件。 您可以在写入文件之前转换多个形状。每个形状都将是 IGES 模型中的根实体。

希望我的博客,能帮上你解决学习中工作中所遇到的问题 923

Ubuntu 16.04 dpkg:dpkg: 处理软件包 xxx (--configure)时出错 解决办法

这个博哥非常好,亲测有用 博客链接

qq_38904904的博客 1289

桌面运维工程师面试题汇总(高频完整版)

岗位,覆盖:电脑硬件、系统安装与故障、网络、办公软件、安全、AD域、打印机、日常排错、服务意识。

老韩的Linux云计算架构师进阶之路 922

dpkg: 处理软件包 xxx (--configure)时出错解决方法

2021-10-18 by 崔斐然 dpkg: 处理软件包 xxx (–configure)时出错解决方法 来源:https://blog.youkuaiyun.com/jf_xu/article/details/82285008 dpkg: 处理软件包 libicu-dev (–configure)时出错: 依赖关系问题 - 仍未被配置 dpkg: 依赖关系问题使得 libxml2-dev:amd64 的配置工作不能继续: libxml2-d...

崔斐然的优快云啊CuiFeiran 2万+

RK3588在线更新系统内核的方法

《RK3588设备在线升级系统内核方法》 本文介绍了RK3588设备在线升级系统内核的简易方法。通过将新内核文件boot.img拷贝至目标主机后,使用dd命令配合关键参数(fsync确保写入磁盘、notrunc避免截断分区)进行安全更新,更新后需执行sync同步操作并重启生效。文章特别强调操作过程中断电风险,并扩展说明了Uboot的类似更新方法。该方法避免了现场设备拆卸的麻烦,为嵌入式系统维护提供了实用解决方案。

荻夜的博客 1050

【Altium Designer】Off grid pin解决方法

​今天我画完原理图编译时,出现了太多的黄色(出现warning警告提示)Off grid pin警告,这个警告并不是原理图电气连接出问题了,而是元器件或器件PIN脚没有和栅格对齐造成的原因。再编译还是出现这个警告。 最后经过不断翻阅网上经验和实践,才最终解决,本经验详细记录了解决该警告的有效方法。 解决方案:以下是问题解决步骤... ​

夜半少年的博客 7550

dpkg: 处理软件包 XXX (--configure)时出错:

问题1: dpkg: 处理软件包 redis-server (--configure)时出错:  子进程 已安装 post-installation 脚本 返回错误状态 1 正在处理用于 libc-bin (2.23-0ubuntu3) 的触发器 ... 正在处理用于 systemd (229-4ubuntu10) 的触发器 ... 正在处理用于 ureadahead (0.100.0-19) ...

fly_sky_share的博客 2974

【入门AUTOSAR网络管理测试】AUTOSAR网络管理规范需求解读

AUTOSARAutomotive Open System Architecture,汽车开放系统架构,由全球汽车制造商、部件供应商及其他电子、半导体和软件系统公司联合建立,致力于制定汽车电子软件标准的联盟。网络管理网络管理的目的是使网络中的ECU节点有序的睡眠和唤醒。在没有通信需求的时候睡眠,在需要通信的时候唤醒,可以节约汽车电池的电量。

测试领域技术分享 5166
上一篇: 某大型银行深化系统之十八:性能设计之三
下一篇: Android应用开发之版本更新你莫愁
innovation
博客等级 码龄14年 251粉丝 136原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值