我遇到了一个问题,即所有RPC(无论是提供者还是援助者)都被阻止调用我的服务应用程序。
调用的函数客户端很简单,我确信不会阻塞数小时。(并且没有死锁)
深入了解binder驱动程序,在/ sys / kernel / debug / binder中找到了一些信息。
-from bidner / stats.txt,发现没有任何活页夹帖子"准备就绪":
proc 918
threads: 23
requested threads: 0+15/15
ready threads 0
-from binder / proc / 918,发现一些传入的交易和待处理的交易。 -from anr info,发现高内核cpu使用率
CPU usage from 6506ms to 225ms ago:
90% 918/com.evideostb.cbb.cbbship: 4.1% user + 86% kernel / faults: 11165203 minor
CPU usage from 3444ms to 3956ms later:
100% 918/com.evideostb.cbb.cbbship: 0% user + 100% kernel / faults: 1001251 minor
100% 977/Thread-35507: 0% user + 100% kernel
-try通过android-studio将debuger附加到android进程,发现我的进程一直隐身到android-studio,而我仍然可以使用它。
-try到gdb,并且线程应用所有信息,许多线程(或者所有java thead)打印堆栈就像这样(似乎是无限的):
#0 0xb6e45968 in syscall () from G:\kdroid\tmp\lib\libc.so
#1 0xb4ff76a6 in art::ConditionVariable::Wait(art::Thread*) ()
from G:\kdroid\tmp\lib\libart.so
#2 0xb4ff76a6 in art::ConditionVariable::Wait(art::Thread*) ()
from G:\kdroid\tmp\lib\libart.so
#3 0xb4ff76a6 in art::ConditionVariable::Wait(art::Thread*) ()
from G:\kdroid\tmp\lib\libart.so
......
找不到JDWP thead堆栈
找不到Thread-35507
此应用程序过于复杂,无法将所有代码放在此处,只需粘贴参考代码即可。
- 服务:
public void onCreate() {
super.onCreate();
Notification notification = new Notification();
notification.flags = notification.flags
| Notification.FLAG_NO_CLEAR;
startForeground(
getClass().hashCode(),
notification);
}
-OnBind像这样返回援助:
interface ICbbServiceBinder{
IBinder getCbbService(int serviceEnumOrdinal);
}
实现:
private static SparseArray<IBinder> mBinders = new SparseArray<>();
public static IBinder getFunction(CbbClient.ServiceName name){
return mBinders.get(name.ordinal());
}
-Client side:
private final SparseArray<IInterface> mCache = new SparseArray<>();
public IInterface getService(ServiceName name){
if (!mIsInit){
Log.e(TAG, "getService: cbb remote server down");
return null;
}
int nameOrdinal = name.ordinal();
synchronized (mCache) {
IInterface iInterface = mCache.get(nameOrdinal);
if (iInterface == null) {
IBinder binder;
try {
binder = mCbbServer.getCbbService(nameOrdinal);
} catch (RemoteException e) {
Log.e(TAG, "getService: can't get service from cbb remote service");
return null;
}
switch (name) {
case CBB_CORE:
iInterface = ICbbCore.Stub.asInterface(binder);
break;
case ......//select binder by name
default:
iInterface = null;
break;
}
mCache.put(nameOrdinal, iInterface);
}
return iInterface;
}
}
然后客户端可以通过getService使用IInterface返回来执行RPC。