zoukankan      html  css  js  c++  java
  • Android远程服务

    一、远程服务主要代码

    1.IService.aidl

    package com.shz.remoteservice;
    
    interface IService {
        String getTicketInfoById(int id);
    }
    View Code

      编译aidl文件自动生成的IService.java文件(存在于gen目录下)

    /*
     * This file is auto-generated.  DO NOT MODIFY.
     * Original file: E:\Code\Java\远程服务\src\com\shz\remoteservice\IService.aidl
     */
    package com.shz.remoteservice;
    public interface IService extends android.os.IInterface
    {
    /** Local-side IPC implementation stub class. */
    public static abstract class Stub extends android.os.Binder implements com.shz.remoteservice.IService
    {
    private static final java.lang.String DESCRIPTOR = "com.shz.remoteservice.IService";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
    this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an com.shz.remoteservice.IService interface,
     * generating a proxy if needed.
     */
    public static com.shz.remoteservice.IService asInterface(android.os.IBinder obj)
    {
    if ((obj==null)) {
    return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin!=null)&&(iin instanceof com.shz.remoteservice.IService))) {
    return ((com.shz.remoteservice.IService)iin);
    }
    return new com.shz.remoteservice.IService.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder()
    {
    return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
    switch (code)
    {
    case INTERFACE_TRANSACTION:
    {
    reply.writeString(DESCRIPTOR);
    return true;
    }
    case TRANSACTION_getTicketInfoById:
    {
    data.enforceInterface(DESCRIPTOR);
    int _arg0;
    _arg0 = data.readInt();
    java.lang.String _result = this.getTicketInfoById(_arg0);
    reply.writeNoException();
    reply.writeString(_result);
    return true;
    }
    }
    return super.onTransact(code, data, reply, flags);
    }
    private static class Proxy implements com.shz.remoteservice.IService
    {
    private android.os.IBinder mRemote;
    Proxy(android.os.IBinder remote)
    {
    mRemote = remote;
    }
    @Override public android.os.IBinder asBinder()
    {
    return mRemote;
    }
    public java.lang.String getInterfaceDescriptor()
    {
    return DESCRIPTOR;
    }
    @Override public java.lang.String getTicketInfoById(int id) throws android.os.RemoteException
    {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    java.lang.String _result;
    try {
    _data.writeInterfaceToken(DESCRIPTOR);
    _data.writeInt(id);
    mRemote.transact(Stub.TRANSACTION_getTicketInfoById, _data, _reply, 0);
    _reply.readException();
    _result = _reply.readString();
    }
    finally {
    _reply.recycle();
    _data.recycle();
    }
    return _result;
    }
    }
    static final int TRANSACTION_getTicketInfoById = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    }
    public java.lang.String getTicketInfoById(int id) throws android.os.RemoteException;
    }
    View Code

    2.TicketService.java

    package com.shz.remoteservice;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    /**
     * 后台服务(组件),提供查询电影票相关信息
     * @author SHZ
     *
     */
    public class TicketService extends Service {
    
        private final static String TAG = "TicketService";
        private List<Ticket> tickets;
        
        @Override
        public IBinder onBind(Intent intent) {
            Log.i(TAG, "onBind 服务绑定成功");
            // 2.Activity绑定服务成功之后,服务返回给Activity一个IBinder类型的对象,
            // 通过该对象,Activity就可以和服务进行交互了,就像一个代理一样
            return new TicketBinder();
        }
    
        @Override
        public void onCreate() {        
            super.onCreate();
            Log.i(TAG, "onCreate 服务创建成功");
            this.tickets = new ArrayList<Ticket>();
            this.tickets.add(new Ticket(1, "变形金刚4", 103));
            this.tickets.add(new Ticket(2, "窃听风云3", 86));
            this.tickets.add(new Ticket(3, "反腐风暴", 75));
        }
    
        @Override
        public void onStart(Intent intent, int startId) {
            Log.i(TAG, "onStart 服务启动");
            super.onStart(intent, startId);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i(TAG, "onStartCommand 服务启动");
            return super.onStartCommand(intent, flags, startId);
        }
        
        @Override
        public boolean onUnbind(Intent intent) {
            Log.i(TAG, "onUnbind 服务解绑成功");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i(TAG, "onDestroy 服务销毁成功");
        }
        
        private Ticket getTicket(int id)
        {
            for(Ticket ticket:this.tickets)
            {
                if(ticket.Id == id)
                {
                    return ticket;
                }
            }
            
            return null;
        }
        
        /**
         * 服务内部方法:查询电影票信息
         * @param id 
         * @return
         */
        public String getTicketInfo(int id)
        {
            Ticket ticket = this.getTicket(id);
            if(ticket == null)
            {
                return "未查询到该电影票信息";
            }
            else
            {
                return ticket.toString();
            }
        }
        
        /**
         * 服务内部方法(测试用,没有意义):更新电影票价格
         * @param id
         * @param newPrice
         */
        public void updateTicketPrice(int id, float newPrice)
        {
            Ticket ticket = this.getTicket(id);
            if(ticket != null)
            {
                ticket.Price = newPrice;
            }
        }
        
        /**
         * 自定义一个代理类,继承Binder并实现IService接口。
         * 服务会返回该类的一个实例给调用者,调用者可通过该实例调用相应的类方法
         * @author SHZ
         *
         */
        private class TicketBinder extends IService.Stub
        {
            /**
             * 实现IService接口中的方法,调用服务内部的方法,这样调用服务的Activity就可以获取电影票信息了
             */
            @Override
            public String getTicketInfoById(int id) {
                return getTicketInfo(id);
            }
            
            /**
             * 由于该方法并未在IService接口中定义,故调用者无法使用该方法
             * @param id
             * @param newPrice
             */
            public void updateTicketPrice(int id,float newPrice)
            {
                updateTicketPrice(id, newPrice);
            }
            
        }
    
    }
    View Code

    3.Ticket.java(实体类)

    package com.shz.remoteservice;
    
    public class Ticket {
        public int Id;
        public String Name;
        public float Price;
        
        public Ticket(int id, String name, float price) {
            Id = id;
            Name = name;
            Price = price;
        }
        
        @Override
        public String toString() {
            return "您查询的电影是:"+this.Name+",票价为:"+this.Price;
        }
    }
    View Code

    4.清单配置文件AndroidManifest.xml

    <service android:name="com.shz.remoteservice.TicketService">
                <intent-filter>
                    <!-- 如果用于远程服务,则需指定action -->
                    <action android:name="com.shz.TICKETSERVICE"/>
                </intent-filter>
            </service>
    View Code

    二、调用远程服务的代码

    1.把远程服务工程里面的IService.aidl文件(包括包名)拷贝到调用者的工程中

    2.调用代码

    package com.shz.callremoteservice;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.shz.remoteservice.IService;
    
    public class MainActivity extends Activity {
    
        private TicketServiceConnection conn;
        private IService ticketBinder;
        private EditText txtTicketId;
        private TextView lblTicketInfo;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            txtTicketId = (EditText) findViewById(R.id.txtTicketId);
            lblTicketInfo = (TextView) findViewById(R.id.lblTicketInfo);
           
        }
    
        private class TicketServiceConnection implements ServiceConnection
        {
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // 2.绑定服务成功之后,后台服务会返回IBinder类型的 service 对象,通过该对象可以间接调用后台服务的方法
                ticketBinder = IService.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                
            }
            
        }
        
        /**
         * 绑定服务
         * @param view
         */
        public void bindService(View view) {
            Intent service = new Intent();
            service.setAction("com.shz.TICKETSERVICE");    // 通过action指定要调用的服务
            // 1.绑定服务
            // service:服务意图
            // new TicketServiceConnection():与后台服务连接的对象,接收后台服务信息
            // BIND_AUTO_CREATE:如果服务没有被创建,则自动创建并绑定
            conn = new TicketServiceConnection();
            bindService(service, conn, BIND_AUTO_CREATE);
        }
        
        @Override
        protected void onDestroy() {
            try {
                unbindService(conn);
            } catch (Exception e) {
            }
            super.onDestroy();
        }
        
        public void callServiceMethod(View view) {
            if(this.ticketBinder == null)
            {
                Toast.makeText(this, "请先绑定服务", 1).show();
            }
            else
            {
                String strTicketId = this.txtTicketId.getText().toString().trim();
                if(TextUtils.isEmpty(strTicketId))
                {
                    Toast.makeText(this, "请输入电影票Id", 1).show();
                    return;
                }
                
                try {
                    // 3.调用IBinder对象的方法
                    String ticketInfo = this.ticketBinder.getTicketInfoById(Integer.parseInt(strTicketId));
                    this.lblTicketInfo.setText(ticketInfo);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
    }
    View Code

    3.前台UI布局代码

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.shz.localservice.MainActivity"
        tools:ignore="MergeRootFrame" >
        
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="bindService"
            android:text="绑定服务" />
    
        <EditText 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入电影票Id"
            android:id="@+id/txtTicketId"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="callServiceMethod"
            android:text="查询" />
        
        <TextView 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/lblTicketInfo"
            android:textColor="#ff0000"/>
    
    </LinearLayout>
    View Code

    调用服务前必须先绑定服务(当然了,远程服务必须首先启动起来)

    调用结果截图:

  • 相关阅读:
    sl跨域访问学习笔记2
    XAML标记扩展
    充分利用资源,实践中创新
    程序集版本号与文件版本号的区别
    项目管理: 软件质量的可靠保证
    未能将临时文件复制到输出目录中
    IBM DB2 UDB V8.1®,Oracle9i R2®,Microsoft SQL Server 2000® 技术比较分析
    Asp.net 1.0 升级至 ASP.NET 2.0十个问题总结
    The remote procedure call failed and did not execute的解决办法
    快速解决IIS5故障一例
  • 原文地址:https://www.cnblogs.com/shaomenghao/p/3947457.html
Copyright © 2011-2022 走看看