zoukankan      html  css  js  c++  java
  • Android远程服务AIDL开发过程中容易遇见的两个问题

    问题 一

    JavaBinder: Uncaught remote exception! (Exceptions are not yet supported across processes.) java.lang.RuntimeException:Can't create handler inside thread that has not called Looper.prepare()

    toast提示异常.jpg

    问题描述

    • 在service中的一个方法中,执行两种提示:一种是 Log 打印数据,另一种是 Toast 提示。(都是在service当前运行的线程中)
    • Log打印数据成功,Toast提示抛出异常(即问题一)。
      代码示例
    public class AliPayService extends Service {
    ...
        //模拟支付方法
        public boolean aliPay(int money) {
            Log.e("AIDL", "服务线程:" + Thread.currentThread().getName());
            if (money > 100) {
                Toast.makeText(this, "土豪,购买成功...", Toast.LENGTH_SHORT).show();
                //handler.sendEmptyMessage(1);
                return true;
            } else {
                Toast.makeText(this, "钱太少啦,购买失败...", Toast.LENGTH_SHORT).show();
                //handler.sendEmptyMessage(0);
                return false;
            }
        }
    }
    

    问题解决方案说明

    • service服务是运行在service线程中,属于子线程。Toast提示属于更新UI的操作,必须放在主线程中执行。所以会抛出:Can't create handler inside thread that has not called Looper.prepare()异常
    • 切记:::服务内如果需要执行UI更新,可以发送消息通知主线程执行。

    问题 二

    Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent
    bind开启服务异常.jpg

    问题描述

    • 应用A 调用 应用B 中服务的某个方法。AIDL操作
    • Android4.4版本的手机调用服务方法正常
    • Android5.0版本之后的手机调用服务方法抛出该异常

    代码示例(在应用B中以bind方式调用应用A中的服务)

    //应用A中 bind方式开启应用B的指定服务
    class MainActivity : AppCompatActivity() {
        //服务连接对象
        private var connection: MyServiceConnection? = null
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            //bind方式开启服务
            val intent = Intent()
            intent.action = "应用B包名.service.pay.xxx"
            //intent.setPackage("应用B包名")
            connection = MyServiceConnection()
            bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }
    }
    
    //应用B中 service 在清单文件中的配置代码
    <!--调用远程服务,需要通过bind方式启动服务,调用服务方法-->
    <service android:name=".service.pay.AliPayService">
        <intent-filter>
            <action android:name="com.zero.notes.service.pay.xxx"/>
        </intent-filter>
    </service>
    

    问题解决方案说明

    • 使用AIDL执行跨进程操作的时候,如:应用A调用应用B中的支付服务,除了指定服务定义好的 action 之外,切记也要使用方法setPackage("包名")指定应用B的包名。(上述代码中,放开注释掉的一行代码://intent.setPackage("应用B包名") ,就可以解决该异常。)
  • 相关阅读:
    iOS开发时,在Xcode中添加多个Targets进行版本控制
    如何给苹果公司发邮件?
    快快快!27个提升效率的iOS开源库推荐
    史上最全的常用iOS的第三方框架
    Ajax提交与传统表单提交的区别说明
    js原生ajax请求get post笔记
    查看iOS Crash logs
    如何提高iOS开发能力
    iOS 常用的#define合集
    Xcode编译错误和警告汇总
  • 原文地址:https://www.cnblogs.com/io1024/p/11572761.html
Copyright © 2011-2022 走看看