• Android 学习笔记 Service服务与远程通信...(AIDL)


    PS:这一章节看的我有几分迷茫,不是很容易理解...不过还好总算是明白了一大半了...基本的迷惑是解决了...

    学习内容:

    1.跨应用启动服务...

    2.跨应用绑定服务...

    3.跨应用实现通信...

    由于5.0版本之前和5.0版本之后是有很大的区别的,因此我都会在这里进行具体的介绍...

    1.跨应用启动服务...

      跨应用启动服务,其实就是多个应用程序之间产生一种沟通关系,应用程序之间可以进行通信或者是完成一些其他的互动,总而言之,就是在我本身的应用程序中去启动其他应用程序的某个服务,这就完成了跨应用启动服务...

    2.跨应用绑定服务...

      跨应用绑定服务和跨应用启动服务基本类似,就是跨应用实现了绑定,调用的函数不一样而已...在这里我就不进行粘贴代码了,因为没什么必要,仅仅是跨应用启动和绑定服务是没有任何意义的,因为应用之间只有实现了通信,那么跨应用才有必要,否则我光绑定或者只是启动服务,而无法完成通信,那就一点意义都没有了...因此重点还是下面这点...

    3.跨应用实现通信...

      跨应用实现通信,这个东西是非常重要的,应用程序之间,难免是需要通信的...这里完成通信一般都是使用绑定服务来完成,也就是说,都是使用bindService()来完成的..在这里呢Android机制为我们提供了一个AIDL服务,来方便我们完成跨进程通信,那么什么是AIDL呢,就是Android接口语言..它用来公开服务的接口,然后是其他的应用程序也可以访问这个应用程序内部的服务..是个非常猛的机制...那么如何去使用呢...

      在这里我建立两个应用程序,一个是服务端,一个是客户端...服务端用来提供数据,客户端用来获取数据...

    i.首先我们先建立一个服务端...

      新建一个项目..exam_Cilent,包名为org.hnist.demo。。然后点击包文件,New->File,然后会弹出窗口,在最下方输入IPerson.aidl。。直接Finish就行了...然后编辑我们的aidl文件..

    package org.hinst.demo;
    interface IPerson{
        void setName(String name);
        void setAge(int age);
        void setEmail(String email);
        String display();
    } 

    在正常情况下在R.java文件下会自动生成一个IPerson.java文件...这个需要一点点时间...如果实在是没生成,那就Rebuild project...然后就搞定了...

      然后再建立一个IPersonImp.java文件,这个文件需要继承IPerson.Stub类,这里是核心部分...想必大家都明白,我们定义了一个接口,必然需要有一个类去实现这个接口..这个类才是真正能被客户端调用的东西..

    package org.hinst.demo;
    
    import android.os.RemoteException;
    
    public class IPersonImpl extends IPerson.Stub{
    
        private String name="ClearLove";
        private int age=20;
        private String email="zxf@163.com";
        @Override
        public void setName(String name) throws RemoteException {
            // TODO Auto-generated method stub
            this.name=name;
        }
    
        @Override
        public void setAge(int age) throws RemoteException {
            // TODO Auto-generated method stub
            this.age=age;
        }
    
        @Override
        public void setEmail(String email) throws RemoteException {
            // TODO Auto-generated method stub
            this.email=email;
        }
    
        @Override
        public String display() throws RemoteException {
            // TODO Auto-generated method stub
            return "姓名:"+name+"年龄"+age+"邮箱"+email;
        }
    
    }

    服务端的MainActivity.java文件保持原样就行...什么东西都不加也可以...也可以自己定义一些代码调用服务..

      最后我们需要在AndroidManifest.xml文件中进行一些相应的配置...这个文件是必须要进行配置的,否则就会出现问题...只需要在</activity>和</application>之间加入下列代码就完成了...这个在5.0版本之前都是允许的,但是在5.0版本以后是不允许再这样做的...

    <service android:name="MyRemoteService">
                <intent-filter>
                    <action android:name="org.hinst.demo.MyRemoteService"/>
                </intent-filter>
    </service>

     ii.这样服务端我们就配置完了...接下来就是客户端了...客户端相对就很简单....只是注意一点细节就可以了...我们再次建立另一个项目...包名为org.exam...然后再新建一个包..这个包用来存放...服务端的aidl文件...包名要和客户端保存的adil文件的包名相同,就是org.hnist.demo...然后再次新建一个aidl文件,输入的内容与服务端的一样...完成后,在客户端的R.java文件也会生成一个文件...这样客户端的aidl就配置好了...

    然后就是客户端进行调用了...在MainActivity中进行调用...

    package org.hnist.exam;
    
    import org.hinst.demo.IPerson;
    
    import com.example.exam6_7client.R;
    
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.view.Menu;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.TextView;
    
    public class MainActivity extends Activity implements View.OnClickListener {
    
        private IPerson iPerson;
        private TextView textview;
        Intent intent=new Intent("org.hinst.demo.MyRemoteService");
        private ServiceConnection con=new ServiceConnection() {
            
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                iPerson=null;
            }
            
            @Override
            synchronized public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                iPerson=IPerson.Stub.asInterface(service);
            }
        };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            findViewById(R.id.start).setOnClickListener(this);
            bindService(intent, con, Service.BIND_AUTO_CREATE);
            textview=(TextView) findViewById(R.id.show);
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            switch(v.getId()){
            case R.id.start:
                try {
                    iPerson.setName("Clearlove");
                    String msg=iPerson.display();
                    MainActivity.this.textview.setText(msg);
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
            }
        }
        protected void onDestroy(){
            unbindService(con);
            super.onDestroy();
        }
    
    }

      布局文件我就不进行粘贴了....我们先启动服务端完成相应的aidl文件的配置,然后调用客户端,这样在触发按钮的时候,客户端就会输出服务端的信息了...这样也就完成了客户端与服务端的通信...

      在5.0版本以后呢,我们就不能使用配置AndroidManifest.xml文件,使用隐式的Intent已经无法完成多个应用程序之间的通信了...5.0版本之后..aidl文件的配置是一样的,没有任何的变化,唯一的变化就是需要使用显式的Intent,去进行传递...这个的原因我还真就不是很清楚...

      如何传递呢?就是这样...

    serviceintent =new Intent();
    serviceintent.setComponent(new ComponentName("com.example.myserviceapp","com.example.myserviceapp.AppMyService"));

      只要把Intent建立的对象制定一个主键值,这个主键值有两个参数,一个是我们要调用的服务的包名,一个是这个服务名....然后这样就完成了主键值的赋值....然后再次使用bindservice(serviceintent,this,Server.BIND_AUTO_CREATE)方法在进行传递...就完成了...最后放一个完整的代码,方便大家理解...这里使用了一个打包的机制..大家不用弄懂..关键是看服务端与客户端的实现...其实我上面的代码也是可以运行的...上面的更加的简单...

      这个跨进程通信不是很好理解,实际上并不难,只要理解了就会发现,其实没什么难的东西...关键还是看自己是否用心研究...

    这个是服务端的代码...

    http://files.cnblogs.com/files/RGogoing/AIDLService.rar

    这个是客户端...

    http://files.cnblogs.com/files/RGogoing/AIDLClient.rar

     

  • 相关阅读:
    DCR挖矿成本¥355.92,市价¥346.24——五大币种挖矿成本分析 2018-08-7
    智者见智——区块链3.0与未来
    梭哈10万入场,拿住不放,3年后收益过十亿,币圈传奇—大空翼
    从路人甲到叱咤币圈的神话:“打死也不卖币”的宝二爷
    小白眼里的区块链和币圈 —— 持币待涨的故事
    区块链如何赋能网络互助行业?来自众托帮+区块链的应用、车车助+纷享车链AutoChain应用
    中国青年网记者-阿里巴巴王坚:互联网已成为世界发展的基础设施
    读者咩叭:畅谈经济未来
    中青网财经:请一位心理学博士当CTO 只有马云敢这么做
    云科技时代:阿里云创造者写了《在线》,这是一本怎样的书?
  • 原文地址:https://www.cnblogs.com/RGogoing/p/4554799.html
Copyright © 2020-2023  润新知