android java ibinder_Java IBinder.isBinderAlive方法代码示例

本文介绍了一种在Android环境中获取已注册服务的IBinder对象的方法。该方法首先尝试从本地缓存中查找请求的服务,如果未找到,则通过远程服务通道获取,并进行必要的包装和缓存更新。

import android.os.IBinder; //导入方法依赖的package包/类

/**

* 获取已注册服务的IBinder对象,前提是该服务是静态服务,即默认一直存在,或者自己已经启动并且向我们注册过;

* 注意不能通过此借口获取一个插件的服务,除非明确知道该插件的服务已经主动注册过,否则使用getPluginService()

*

* @param context

* @param serviceName 请求获取的service名称

* @return 所请求的service实现对象

*/

public static IBinder getService(Context context, String serviceName) {

if (DEBUG) {

Log.d(TAG, "[getService] begin = " + SystemClock.elapsedRealtime());

}

IBinder service = null;

/**

* 先考虑本地缓存

*/

SoftReference ref = sCache.get(serviceName);

if (ref != null) {

service = ref.get();

if (service != null) {

if (service.isBinderAlive() && service.pingBinder()) {

if (DEBUG) {

Log.d(TAG, "[getService] Found service from cache: " + serviceName);

Log.d(TAG, "[getService] end = " + SystemClock.elapsedRealtime());

}

return service;

} else {

sCache.remove(serviceName);

}

}

}

IServiceChannel serviceChannel = getServerChannel(context);

if (serviceChannel == null) {

return null;

}

try {

service = serviceChannel.getService(serviceName);

if (service != null) {

if (DEBUG) {

Log.d(TAG, "[getService] Found service from remote service channel: " + serviceName);

}

service = ServiceWrapper.factory(context, serviceName, service);

sCache.put(serviceName, new SoftReference(service));

}

} catch (RemoteException e) {

if (DEBUG) {

Log.e(TAG, "[getService] Error when getting service from service channel...", e);

}

}

if (DEBUG) {

Log.d(TAG, "[getService] end = " + SystemClock.elapsedRealtime());

}

return service;

}

package com.isa.navi.library.manager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; import androidx.annotation.GuardedBy; import com.isa.navi.library.IISANaviProxy; import com.isa.navi.library.constant.Const; import com.isa.navi.library.map.MapProxy; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * @author haoj * @description description * @date 2023-06-20 */ public class ISANaviManager { public static final String TAG = Const.ISA_NAVI + "ServiceManager"; private static final int MSG_MANAGER_INIT = 0; private static final int MSG_CONNECT_RETRY = 1; private static final int MSG_CONNECT_FAIL = 2; private static final int MSG_SERVICE_STATUS = 3; private Context mContext; private Handler mWorkHandler; private HandlerThread mHandlerThread = null; private final ServiceConnection mServiceConnectionListener; @GuardedBy("this") private int mConnectionRetryCount; @GuardedBy("this") private IISANaviProxy mService; @GuardedBy("this") private IBinder mBinder; private IBinder.DeathRecipient mDeathRecipient; private boolean mIsInit = false; private List<IServiceStatusChangeListener> mServiceStatusListeners; private volatile static ISANaviManager mInstance; public static ISANaviManager getInstance() { if (mInstance == null) { synchronized (ISANaviManager.class) { if (mInstance == null) { mInstance = new ISANaviManager(); } } } return mInstance; } private ISANaviManager() { Log.d(TAG, "constructor"); initHandler(); mDeathRecipient = new DeathRecipient(); mServiceStatusListeners = new CopyOnWriteArrayList<>(); mServiceConnectionListener = new ServiceConnectionListener(); MapProxy.getInstance().initServiceManager(this); } public void initialize(Context context) { Log.d(TAG, "initialize:" + mIsInit + " ,getPackageName:" + context.getPackageName()); if (!mIsInit) { mContext = context.getApplicationContext(); if (!mWorkHandler.hasMessages(MSG_MANAGER_INIT)) { mWorkHandler.removeMessages(MSG_MANAGER_INIT); } mWorkHandler.sendEmptyMessage(MSG_MANAGER_INIT); mIsInit = true; } } private void handleMessage(Message msg) { Log.d(TAG, "handleMessage msg:" + msg.what); switch (msg.what) { case MSG_MANAGER_INIT: case MSG_CONNECT_RETRY: startService(); break; case MSG_CONNECT_FAIL: handleReconnect(); break; case MSG_SERVICE_STATUS: boolean isConnect = (boolean) msg.obj; if (isConnect) { MapProxy.getInstance().initialize(); } notifyServiceStatusChange(isConnect); break; } } class DeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Log.d(TAG, "binderDied:"); if (mBinder != null) { mBinder.unlinkToDeath(this, 0); } mBinder = null; handleRemoteException(); sendServiceStatusMessage(false); } } class ServiceConnectionListener implements ServiceConnection { public void onServiceConnected(ComponentName name, IBinder service) { Log.d(TAG, "onServiceConnected name:" + name); try { mBinder = service; mBinder.linkToDeath(mDeathRecipient, 0); mService = IISANaviProxy.Stub.asInterface(service); sendServiceStatusMessage(true); } catch (RemoteException e) { e.printStackTrace(); } } public void onServiceDisconnected(ComponentName name) { Log.d(TAG, "onServiceDisconnected name: " + name); mBinder = null; handleRemoteException(); sendServiceStatusMessage(false); } } private void sendServiceStatusMessage(boolean isConnect) { if (mWorkHandler.hasMessages(MSG_SERVICE_STATUS)) { mWorkHandler.removeMessages(MSG_SERVICE_STATUS); } Message msg = Message.obtain(); msg.what = MSG_SERVICE_STATUS; msg.obj = isConnect; mWorkHandler.sendMessage(msg); } private void startService() { Intent intent = new Intent(); intent.setComponent(new ComponentName(Const.SVR_PACKAGE_NAME, Const.SVR_SERVICE_NAME)); intent.setAction(Const.SVR_ACTION_NAME); Log.d(TAG, "startService: =========>" + mContext.getPackageName()); boolean bound = mContext.bindService(intent, mServiceConnectionListener, Context.BIND_AUTO_CREATE); Log.d(TAG, "startService bound:" + bound); if (!bound) { ++mConnectionRetryCount; if (mConnectionRetryCount > 20) { Log.d(TAG, "startService cannot bind to privacy service after max retry"); if (!mWorkHandler.hasMessages(MSG_CONNECT_RETRY)) { mWorkHandler.sendEmptyMessage(MSG_CONNECT_FAIL); } } else { if (!mWorkHandler.hasMessages(MSG_CONNECT_RETRY)) { mWorkHandler.sendEmptyMessageDelayed(MSG_CONNECT_RETRY, 500L); Log.d(TAG, "startService bindService fail retry"); } } } else { mConnectionRetryCount = 0; mWorkHandler.removeMessages(MSG_CONNECT_FAIL); mWorkHandler.removeMessages(MSG_CONNECT_RETRY); Log.d(TAG, "startService bindService success"); } } private synchronized IISANaviProxy getService() { Log.d(TAG, "getIProxyThrow mService:" + mService); synchronized (ISANaviManager.class) { if (mService == null) { startService(); } } return mService; } private void handleRemoteException() { Log.d(TAG, "handleRemoteException: "); if (!mWorkHandler.hasMessages(MSG_CONNECT_FAIL)) { mWorkHandler.sendEmptyMessageDelayed(MSG_CONNECT_FAIL, 500L); Log.d(TAG, "handleRemoteException bindService fail retry"); } } private void initHandler() { Log.i(TAG, "determineEventHandler is called mHandlerThread:" + mHandlerThread); if (null == mHandlerThread) { Log.i(TAG, "determineEventHandler mWorkHandler"); mHandlerThread = new HandlerThread("ServiceManager"); mHandlerThread.start(); Looper looper = mHandlerThread.getLooper(); if (looper == null) { Log.e(TAG, "determineEventHandler mHandlerThread.getLooper() == null"); looper = Looper.getMainLooper(); } mWorkHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { Log.i(TAG, "determineEventHandler msg: " + msg.what); ISANaviManager.this.handleMessage(msg); } }; } } private void handleReconnect() { Log.d(TAG, "handleReconnect:"); synchronized (this) { mWorkHandler.removeMessages(MSG_CONNECT_RETRY); mWorkHandler.removeMessages(MSG_CONNECT_FAIL); mConnectionRetryCount = 0; mService = null; mContext.unbindService(mServiceConnectionListener); mWorkHandler.sendEmptyMessageDelayed(MSG_CONNECT_RETRY, 500L); } } protected IBinder getClientBinder(String serviceName) { Log.d(TAG, "getClientBinder:" + serviceName + " ,mIsInit:" + mIsInit); if (!mIsInit) { throw new IllegalStateException("getClientBinder must call init in application first"); } try { IISANaviProxy service = getService(); IBinder binder = service.getService(serviceName); if (binder == null) { Log.d(TAG, "getClientBinder could not get binder for service:" + serviceName); return null; } return binder; } catch (Exception e) { e.printStackTrace(); handleRemoteException(); } return null; } protected String getPackageName() { return mContext.getPackageName(); } /** * 判断服务是否可用 * * @return */ protected boolean isAvailable() { boolean ret = false; synchronized (this) { ret = (mService != null && mBinder != null && mBinder.isBinderAlive() && mBinder.pingBinder()); } if (!ret) { startService(); synchronized (this) { ret = (mService != null && mBinder != null && mBinder.isBinderAlive() && mBinder.pingBinder()); } } Log.d(TAG, "isAvailable: ret " + ret); return ret; } public void registerServiceStatusListener(IServiceStatusChangeListener listener) { if (null != listener) { if (!mServiceStatusListeners.contains(listener)) { mServiceStatusListeners.add(listener); } } } public void unregisterServiceStatusListener(IServiceStatusChangeListener listener) { if (null != listener && mServiceStatusListeners.contains(listener)) { mServiceStatusListeners.remove(listener); } } private void notifyServiceStatusChange(boolean isConnect) { Iterator<IServiceStatusChangeListener> iterator = mServiceStatusListeners.iterator(); while (iterator.hasNext()) { IServiceStatusChangeListener l = iterator.next(); l.onServiceStatusChange(isConnect); } } }
08-20
----- pid 4499 at 2025-08-13 17:47:06.412954464+0530 ----- Cmd line: com.android.vending Build fingerprint: 'realme/RMX3944IN/RE6083L1:16/BP2A.250605.015/V.R4T2.51a3565-32a1269-32b6971:user/release-keys' ABI: 'arm64' Build type: optimized Debug Store: 3,12,47262::ID:5,C:E,T:46657||ID:5,C:S,T:46656,N:SvcBind,D:rebind=false;act=com.google.android.play.core.splitinstall.BIND_SPLIT_INSTALL_SERVICE;cmp=null;pkg=com.android.vending||ID:4,C:E,T:46656||ID:4,C:S,T:46651,N:SvcCreate,D:name=com.google.android.finsky.splitinstallservice.SplitInstallService;pkg=com.android.vending||ID:3,C:E,T:46648||ID:0,C:P,T:46644,N:GoAsync,D:tname=main;tid=2;prid=db935f9||ID:3,C:S,T:46636,N:BcRcv,D:tname=main;tid=2;act=android.intent.action.SIM_STATE_CHANGED;cmp=ComponentInfo{com.android.vending/com.google.android.finsky.simhandler.SimStateReceiver};pkg=null;prid=db935f9||ID:0,C:P,T:45285,N:LooperMsg,D:code=110;trgt=android.app.ActivityThread$H;elapsed=3108||ID:1,C:E,T:45285||ID:2,C:E,T:42999||ID:2,C:S,T:42999,N:SchRcv,D:tname=binder:4499_1;tid=46||ID:1,C:S,T:42177,N:BindApp;; suspend all histogram: Sum: 126us 99% C.I. 3us-36us Avg: 12.600us Max: 36us DALVIK THREADS (95): "main" prio=5 tid=1 Blocked | group="main" sCount=1 ucsCount=0 flags=1 obj=0x74c44f88 self=0xb400007dd64d3000 | sysTid=4499 nice=-10 cgrp=top-app sched=0/0 handle=0x7e88f5b098 | state=S schedstat=( 272241226 31277003 547 ) utm=15 stm=11 core=6 HZ=100 | stack=0x7fed25c000-0x7fed25e000 stackSize=8188KB | held mutexes= at mzx.d(PG:56) - waiting to lock <0x06a417dc> (a java.util.HashMap) held by thread 19 at mzx.c(PG:2) at abth.b(PG:17) at absz.F(PG:61) at zzzi.T(PG:133) at absz.T(PG:111) at odd.run(PG:937) at android.os.Handler.handleCallback(Handler.java:1027) at android.os.Handler.dispatchMessage(Handler.java:108) at android.os.Looper.loopOnce(Looper.java:298) at android.os.Looper.loop(Looper.java:408) at android.app.ActivityThread.main(ActivityThread.java:9952) at java.lang.reflect.Method.invoke(Native method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:613) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1074) DumpLatencyMs: 3.44646 "BlockingExecutor #0" prio=5 tid=19 TimedWaiting | group="main" sCount=1 ucsCount=0 flags=1 obj=0x2179920 self=0xb400007d39a65c00 | sysTid=4779 nice=1 cgrp=top-app sched=0/0 handle=0x7d2333b500 | state=S schedstat=( 4840693 46088770 11 ) utm=0 stm=0 core=0 HZ=100 | stack=0x7d23238000-0x7d2323a000 stackSize=1037KB | held mutexes= at java.lang.Object.wait(Native method) - waiting on <0x04753737> (a java.lang.Object) at java.lang.Object.wait(Object.java:405) at android.app.ActivityThread.acquireProvider(ActivityThread.java:9020) - locked <0x084574a4> (a android.app.ActivityThread$ProviderKey) - locked <0x04753737> (a java.lang.Object) at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:3990) at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:2593) at android.content.ContentResolver.acquireUnstableContentProviderClient(ContentResolver.java:2705) at axki.c(PG:7) at axsf.a(PG:3) at bcjb.b(PG:3) at bciy.a(PG:7) at mzw.a(PG:5) at brna.b(PG:18) - locked <@addr=0x21e0a90> (a brna) at mzx.d(PG:120) - locked <0x06a417dc> (a java.util.HashMap) at mzx.c(PG:2) at obc.m(PG:14) at oax.run(PG:286) at lvf.bb(PG:25) at obe.a(PG:27) at banz.run(PG:128) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:524) at java.util.concurrent.FutureTask.run(FutureTask.java:317) at bmmk.run(PG:11) at otd.run(PG:44) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651) at bfyl.run(PG:59) at java.lang.Thread.run(Thread.java:1119) DumpLatencyMs: 286.277
08-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值