Android四大组件服务之小例子

外部应用调用第三方服务采用AIDL(Android Interface Definition Language)

AIDL即是用来跟外部第三方用来进行通信的接口(创建AIDL项目,在里面申明接口),要想使用内部接口,应先build project产生.java文件。

 

然后通过实现该接口调用内部方法,产生的.java文件中的Stub继承自android.os.Binder实现了AIDL中的接口。

定义的接口方法通过产生的.java文件的抽象类Stub实现,因此实现AIDL中的接口方法即继承自该接口下的.Stub类实现。

private class ThirdPartPlay extends ThirdPartPay.Stub
//ThirdPartPay即是AIDL中的接口
public static abstract class Stub extends android.os.Binder implements com.alibaba.alipay.ThirdPartPay{ }

 将父类强转为接口类型采用asInterface();

public void onServiceConnected(ComponentName name, IBinder service) {
    Log.d(TAG, "ComponentName:" + name);
    Log.d(TAG, "service:" + service);
    thirdPartPay = ThirdPartPay.Stub.asInterface(service);
}

 不同应用之间进行通信时,AIDL必须相同,否则不能产生相同的.java文件

找到该AIDL的文件夹,

将com文件夹复制带另一个项目中去,保证双方产生相同的.java文件。


小栗子

通过模拟支付宝支付界面通过服务发起调转至第三方进行支付。

服务方:

源码:(PayActivity.java)

package com.alibaba.alipay;

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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

public class PayActivity extends Activity implements View.OnClickListener {

    private static final String TAG = PayActivity.class.getName();
    private boolean mBindService;
    private mConnection connection;
    private ThirdPartPay thirdPartPay;
    private EditText pass;
    private Button payBtn;
    private PayService.PayAction payAction;
    private float payMoney;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pay);
        //3.绑定第三方服务
        doBindService();
        InitView();

    }

    private void InitView() {
        Intent intent = getIntent();
        String info = intent.getStringExtra(Constants.KEY_BILL_INFO);
        payMoney = intent.getFloatExtra(Constants.KEY_PAY_MONEY, 0);
        TextView infoTV = this.findViewById(R.id.order_info_tv);
        TextView payMoney = this.findViewById(R.id.pay_money);
        infoTV.setText("支付信息为:" + info);
        payMoney.setText("支付金额为:" + this.payMoney + "元");
        pass = this.findViewById(R.id.password);
        payBtn = this.findViewById(R.id.pay_btn);
        //5.通过用户支付的密码正确与否,是否进行支付
        payBtn.setOnClickListener(this);
    }

    private void doBindService() {
        Intent intent = new Intent();
        intent.setClass(PayActivity.this, PayService.class);
        connection = new mConnection();
        mBindService = bindService(intent, connection, BIND_AUTO_CREATE);
    }

    @Override
    public void onClick(View v) {
        String password = pass.getText().toString().trim();
        if (password.equals("123") && payAction != null) {
            //6.密码正确,进行支付(payAction.Pay()是内部类方法,该方法调用AIDL接口方法传值回第三方)
            payAction.Pay(payMoney);
            Toast.makeText(this, "支付成功!!!!", Toast.LENGTH_SHORT).show();
            //关闭页面
            finish();
            Log.d(TAG,"pay finish!");
        }else {
            Toast.makeText(this, "password inCorrect!!!!", Toast.LENGTH_SHORT).show();
            return;
        }
    }

    private class mConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //内部类的支付方法
            payAction = (PayService.PayAction) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    //销毁服务
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBindService && connection != null) {
            unbindService(connection);
            mBindService = false;
            connection = null;
            thirdPartPay = null;
        }
    }
}

服务(PayService.java)

package com.alibaba.alipay;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.Nullable;

public class PayService extends Service {
    private static final String TAG = "PayService";
    private ThirdPartPlay thirdPartPlay;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        String action = intent.getAction();
        Log.d(TAG,"onBind--action-->"+action);
        if (action != null&&"com.alibaba.alipay.THIRD_PART_PAY".equals(action)) {
            //1.第三方应用拉起服务
            thirdPartPlay = new ThirdPartPlay();
            return thirdPartPlay;
        }
        PayAction payAction = new PayAction();
        return payAction;
    }

    //4.绑定服务后,服务将该支付类返回给支付页面
    public class PayAction extends Binder{

        public void Pay(Float payMoney){
            Log.d(TAG,"支付金额:"+payMoney);
            if (thirdPartPlay!=null) {
                //7.将支付结果回调给第三方
                thirdPartPlay.PaySuccess();
            }
        }
        public void UserCancelPay(){
            if (thirdPartPlay!=null) {
                thirdPartPlay.PayFailed(1,"用户取消支付");
            }
        }
    }


    //2.处理第三方应用的信息,拉起支付页面
    private class ThirdPartPlay extends ThirdPartPay.Stub{
        private ThirdPartResult mCallback;
        @Override
        public void requstPay(String orderInfo, float payMoney, ThirdPartResult callback) {
            this.mCallback = callback;
            //第三方发起支付请求,打开支付界面
            Intent intent = new Intent();
            intent.setClass(PayService.this,PayActivity.class);
            intent.putExtra(Constants.KEY_BILL_INFO,orderInfo);
            Log.d(TAG,"orderInfo:----->"+orderInfo);
            Log.d(TAG,"payMoney:----->"+payMoney);
            intent.putExtra(Constants.KEY_PAY_MONEY,payMoney);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }

        public void PaySuccess(){
            if (mCallback != null) {
                try {
                    //返回给第三方应用,支付成功(该方法在第三方实现,直接调用第三方的接口即可)
                    mCallback.onPaySuccess();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void PayFailed(int ErrorCode,String msg){
            if (mCallback != null) {
                try {
                    //返回给第三方应用,支付失败
                    mCallback.onPayFailed(ErrorCode,msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.alibaba.alipay">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Alipay">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--exported="true"表示可以被第三方调用服务内部方法-->
            <service android:name=".PayService" android:exported="true">
                <intent-filter >
                    <action android:name="com.alibaba.alipay.THIRD_PART_PAY"></action>
                    <category android:name="android.intent.category.DEFAULT"></category>
                </intent-filter>
            </service>
        <activity android:name=".PayActivity"/>
    </application>

</manifest>

activity_pay.xml(支付界面)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/order_info_tv"
        android:textSize="20sp"
        />
    <TextView
        android:layout_width="match_parent"
        android:textSize="20sp"
        android:layout_height="wrap_content"
        android:id="@+id/pay_money"
        android:layout_marginTop="10dp"
        />
    <EditText
        android:layout_width="match_parent"
        android:textSize="20sp"
        android:layout_height="wrap_content"
        android:id="@+id/password"
        android:hint="请输入支付密码"
        />
    <Button
        android:layout_width="match_parent"
        android:textSize="20sp"
        android:layout_height="wrap_content"
        android:text="确认支付"
        android:id="@+id/pay_btn"
        />
</LinearLayout>

 

客户端:

源码:

(MainActivity.java)第三方逻辑层

package com.alibaba.client;

import androidx.appcompat.app.AppCompatActivity;

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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.alipay.ThirdPartPay;
import com.alibaba.alipay.ThirdPartResult;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = MainActivity.class.getName();
    private TextView count;
    private Button buyBtn;
    private Connection connection;
    private boolean isBindService;
    private ThirdPartPay thirdPartPay;
    private String sCount;
    private float fCount;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindAliPayService();
        InitVeiw();
        buyBtn.setOnClickListener(this);
    }

    private void InitVeiw() {
        count = this.findViewById(R.id.count);
        buyBtn = this.findViewById(R.id.buy_btn);
    }

    /**
     * 绑定支付宝服务
     */
    public void bindAliPayService() {
        Intent intent = new Intent();
        intent.setAction("com.alibaba.alipay.THIRD_PART_PAY");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setPackage("com.alibaba.alipay");
        connection = new Connection();
        isBindService = bindService(intent, connection, BIND_AUTO_CREATE);
    }

    private class Connection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "ComponentName:" + name);
            Log.d(TAG, "service:" + service);
            thirdPartPay = ThirdPartPay.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    @Override
    public void onClick(View v) {
        //点击按钮进行充值
        try {
            if (thirdPartPay != null) {
                //调用服务方的方法,开启服务调转至第三方界面,new PayCallPay()将结果传回
                thirdPartPay.requstPay("充值100块钱", 100f, new PayCallPay());
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //复写AIDL接口下的父类方法
    private class PayCallPay extends ThirdPartResult.Stub {
        //此方法由服务方调用,用以确保支付是否成功,成功则调用onPaySuccess()
        @Override
        public void onPaySuccess() throws RemoteException {
            //支付成功,我们就去修改UI上面的内容
            sCount = count.getText().toString();
            fCount = Float.valueOf(sCount)+100.0f;
            String sText =String.valueOf(fCount);
            count.setText(sText);
            Toast.makeText(MainActivity.this, "充值成功!!!", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onPayFailed(int errorCode, String msg) throws RemoteException {
            Toast.makeText(MainActivity.this, "充值失败!!!", Toast.LENGTH_SHORT).show();
        }
    }

    //销毁服务
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (isBindService == true && connection != null) {
            if (isBindService) {
                Log.d(TAG, "销毁第三方服务");
                unbindService(connection);
                connection = null;
                isBindService = false;
            }
        }
    }
}

点击充值界面(main_activity.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="积分"
        android:textSize="30sp"
        android:gravity="center"
         />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="30sp"
        android:gravity="center"
        android:layout_marginTop="20dp"
        android:textColor="#ff0000"
        android:id="@+id/count"
         />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:textSize="30sp"
        android:text="充值100块"
        android:id="@+id/buy_btn"
        />

</LinearLayout>

效果图:

 

AIDL接口(build project)

ThirdPartPay:

// ThirdPartPay.aidl
package com.alibaba.alipay;
import com.alibaba.alipay.ThirdPartResult;

interface ThirdPartPay {
    //发起支付
    void requstPay(String orderInfo,float payMoney,ThirdPartResult callback);

}

 ThirdPartResult:

// ThirdPartResult.aidl
package com.alibaba.alipay;

interface ThirdPartResult {
    //支付成功
    void onPaySuccess();
    //支付失败
    void onPayFailed(in int erroeCode,in String msg);
}

效果显示:

注意:1.绑定服务之后为了防止泄露,必须同时写解绑服务。

    2.服务方传递结果给第三方应用采用回传方式,在AIDL定义接口实现。调用第三方方法即可。

   3.注意四大组件均是通过Intent通信,且在xml文件中进行配置。

   4.Activity返回结果给第三方时:①调用服务内部类方法②内部类调用实现接口的内部类方法③该内部类中方法将调用回传对象的方法,该回传对象通过AIDL形式传给第三方

    

============================================================================

                             学习整理自b站up主程序猿拉大锯的视频

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值