Skip to content

Commit d26ced6

Browse files
committed
feat(dynamic-loader-impl): PluginLoader接口支持跨进程抛出异常
如不支持抛出异常,控制端可能会认为调用成功继续调用其他方法。 Loader所在进程在没有及时Crash退出前收到调用,会出现进一步的异常Crash, 从而出现Loader所在进程打印两次不同的Crash信息。 #802
1 parent 851ba61 commit d26ced6

File tree

1 file changed

+114
-62
lines changed
  • projects/sdk/dynamic/dynamic-loader-impl/src/main/kotlin/com/tencent/shadow/dynamic/loader/impl

1 file changed

+114
-62
lines changed

projects/sdk/dynamic/dynamic-loader-impl/src/main/kotlin/com/tencent/shadow/dynamic/loader/impl/PluginLoaderBinder.kt

+114-62
Original file line numberDiff line numberDiff line change
@@ -37,127 +37,179 @@ internal class PluginLoaderBinder(private val mDynamicPluginLoader: DynamicPlugi
3737
reply: android.os.Parcel?,
3838
flags: Int
3939
): Boolean {
40+
if (reply == null) {
41+
throw NullPointerException("reply == null")
42+
}
4043
when (code) {
4144
IBinder.INTERFACE_TRANSACTION -> {
42-
reply!!.writeString(PluginLoader.DESCRIPTOR)
45+
reply.writeString(PluginLoader.DESCRIPTOR)
4346
return true
4447
}
4548
PluginLoader.TRANSACTION_loadPlugin -> {
4649
data.enforceInterface(PluginLoader.DESCRIPTOR)
4750
val _arg0: String
4851
_arg0 = data.readString()!!
49-
mDynamicPluginLoader.loadPlugin(_arg0)
50-
reply!!.writeNoException()
52+
try {
53+
mDynamicPluginLoader.loadPlugin(_arg0)
54+
reply.writeNoException()
55+
} catch (e: Exception) {
56+
reply.writeException(wrapExceptionForBinder(e))
57+
}
5158
return true
5259
}
5360
PluginLoader.TRANSACTION_getLoadedPlugin -> {
5461
data.enforceInterface(PluginLoader.DESCRIPTOR)
55-
val _result = mDynamicPluginLoader.getLoadedPlugin()
56-
reply!!.writeNoException()
57-
reply.writeMap(_result as Map<*, *>?)
62+
try {
63+
val _result = mDynamicPluginLoader.getLoadedPlugin()
64+
reply.writeNoException()
65+
reply.writeMap(_result as Map<*, *>?)
66+
} catch (e: Exception) {
67+
reply.writeException(wrapExceptionForBinder(e))
68+
}
69+
5870
return true
5971
}
6072
PluginLoader.TRANSACTION_callApplicationOnCreate -> {
6173
data.enforceInterface(PluginLoader.DESCRIPTOR)
6274
val _arg0: String
6375
_arg0 = data.readString()!!
64-
mDynamicPluginLoader.callApplicationOnCreate(_arg0)
65-
reply!!.writeNoException()
76+
try {
77+
mDynamicPluginLoader.callApplicationOnCreate(_arg0)
78+
reply.writeNoException()
79+
} catch (e: Exception) {
80+
reply.writeException(wrapExceptionForBinder(e))
81+
}
82+
6683
return true
6784
}
6885
PluginLoader.TRANSACTION_convertActivityIntent -> {
6986
data.enforceInterface(PluginLoader.DESCRIPTOR)
70-
val _arg0: android.content.Intent?
71-
if (0 != data.readInt()) {
72-
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
87+
val intent = if (0 != data.readInt()) {
88+
Intent.CREATOR.createFromParcel(data)
7389
} else {
74-
_arg0 = null
90+
reply.writeException(NullPointerException("intent==null"))
91+
return true
7592
}
76-
val _result =
77-
mDynamicPluginLoader.convertActivityIntent(_arg0!!)//todo #32 去掉这个不安全的!!
78-
reply!!.writeNoException()
79-
if (_result != null) {
80-
reply.writeInt(1)
81-
_result.writeToParcel(
82-
reply,
83-
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
84-
)
85-
} else {
86-
reply.writeInt(0)
93+
94+
try {
95+
val _result =
96+
mDynamicPluginLoader.convertActivityIntent(intent)
97+
reply.writeNoException()
98+
if (_result != null) {
99+
reply.writeInt(1)
100+
_result.writeToParcel(
101+
reply,
102+
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
103+
)
104+
} else {
105+
reply.writeInt(0)
106+
}
107+
} catch (e: Exception) {
108+
reply.writeException(wrapExceptionForBinder(e))
87109
}
88110
return true
89111
}
90112
PluginLoader.TRANSACTION_startPluginService -> {
91113
data.enforceInterface(PluginLoader.DESCRIPTOR)
92-
val _arg0: android.content.Intent?
93-
if (0 != data.readInt()) {
94-
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
114+
val intent = if (0 != data.readInt()) {
115+
Intent.CREATOR.createFromParcel(data)
95116
} else {
96-
_arg0 = null
117+
reply.writeException(NullPointerException("intent==null"))
118+
return true
97119
}
98-
val _result = mDynamicPluginLoader.startPluginService(_arg0!!)//todo #32 去掉这个不安全的!!
99-
reply!!.writeNoException()
100-
if (_result != null) {
101-
reply.writeInt(1)
102-
_result.writeToParcel(
103-
reply,
104-
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
105-
)
106-
} else {
107-
reply.writeInt(0)
120+
121+
try {
122+
val _result = mDynamicPluginLoader.startPluginService(intent)
123+
reply.writeNoException()
124+
if (_result != null) {
125+
reply.writeInt(1)
126+
_result.writeToParcel(
127+
reply,
128+
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
129+
)
130+
} else {
131+
reply.writeInt(0)
132+
}
133+
} catch (e: Exception) {
134+
reply.writeException(wrapExceptionForBinder(e))
108135
}
109136
return true
110137
}
111138
PluginLoader.TRANSACTION_stopPluginService -> {
112139
data.enforceInterface(PluginLoader.DESCRIPTOR)
113-
val _arg0: android.content.Intent?
114-
if (0 != data.readInt()) {
115-
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
140+
val intent = if (0 != data.readInt()) {
141+
Intent.CREATOR.createFromParcel(data)
116142
} else {
117-
_arg0 = null
143+
reply.writeException(NullPointerException("intent==null"))
144+
return true
145+
}
146+
try {
147+
val _result = mDynamicPluginLoader.stopPluginService(intent)
148+
reply.writeNoException()
149+
reply.writeInt(if (_result) 1 else 0)
150+
} catch (e: Exception) {
151+
reply.writeException(wrapExceptionForBinder(e))
118152
}
119-
val _result = mDynamicPluginLoader.stopPluginService(_arg0!!)//todo #32 去掉这个不安全的!!
120-
reply!!.writeNoException()
121-
reply.writeInt(if (_result) 1 else 0)
122153
return true
123154
}
124155
PluginLoader.TRANSACTION_bindPluginService -> {
125156
data.enforceInterface(PluginLoader.DESCRIPTOR)
126-
val _arg0: android.content.Intent?
127-
if (0 != data.readInt()) {
128-
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
157+
val intent = if (0 != data.readInt()) {
158+
Intent.CREATOR.createFromParcel(data)
129159
} else {
130-
_arg0 = null
160+
reply.writeException(NullPointerException("intent==null"))
161+
return true
131162
}
132163
val _arg1 = BinderPluginServiceConnection(data.readStrongBinder())
133164
val _arg2: Int
134165
_arg2 = data.readInt()
135-
val _result = mDynamicPluginLoader.bindPluginService(
136-
_arg0!!,
137-
_arg1,
138-
_arg2
139-
)//todo #32 去掉这个不安全的!!
140-
reply!!.writeNoException()
141-
reply.writeInt(if (_result) 1 else 0)
166+
try {
167+
val _result = mDynamicPluginLoader.bindPluginService(
168+
intent,
169+
_arg1,
170+
_arg2
171+
)
172+
reply.writeNoException()
173+
reply.writeInt(if (_result) 1 else 0)
174+
} catch (e: Exception) {
175+
reply.writeException(wrapExceptionForBinder(e))
176+
}
142177
return true
143178
}
144179
PluginLoader.TRANSACTION_unbindService -> {
145180
data.enforceInterface(PluginLoader.DESCRIPTOR)
146-
mDynamicPluginLoader.unbindService(data.readStrongBinder())
147-
reply!!.writeNoException()
181+
try {
182+
mDynamicPluginLoader.unbindService(data.readStrongBinder())
183+
reply.writeNoException()
184+
} catch (e: Exception) {
185+
reply.writeException(wrapExceptionForBinder(e))
186+
}
148187
return true
149188
}
150189
PluginLoader.TRANSACTION_startActivityInPluginProcess -> {
151190
data.enforceInterface(PluginLoader.DESCRIPTOR)
152-
mDynamicPluginLoader.startActivityInPluginProcess(
153-
Intent.CREATOR.createFromParcel(
154-
data
191+
try {
192+
mDynamicPluginLoader.startActivityInPluginProcess(
193+
Intent.CREATOR.createFromParcel(
194+
data
195+
)
155196
)
156-
)
157-
reply!!.writeNoException()
197+
reply.writeNoException()
198+
} catch (e: Exception) {
199+
reply.writeException(wrapExceptionForBinder(e))
200+
}
158201
return true
159202
}
160203
}
161204
return super.onTransact(code, data, reply, flags)
162205
}
206+
207+
/**
208+
* Binder的内置writeException方法只支持特定几种Exception
209+
* https://developer.android.com/reference/android/os/Parcel.html#writeException(java.lang.Exception)
210+
*/
211+
private fun wrapExceptionForBinder(e: Exception): Exception {
212+
return IllegalStateException(e.message, e.cause)
213+
}
214+
163215
}

0 commit comments

Comments
 (0)