Skip to content

Commit

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

#802
  • Loading branch information
shifujun committed Feb 18, 2022
1 parent 851ba61 commit d26ced6
Showing 1 changed file with 114 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,127 +37,179 @@ internal class PluginLoaderBinder(private val mDynamicPluginLoader: DynamicPlugi
reply: android.os.Parcel?,
flags: Int
): Boolean {
if (reply == null) {
throw NullPointerException("reply == null")
}
when (code) {
IBinder.INTERFACE_TRANSACTION -> {
reply!!.writeString(PluginLoader.DESCRIPTOR)
reply.writeString(PluginLoader.DESCRIPTOR)
return true
}
PluginLoader.TRANSACTION_loadPlugin -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _arg0: String
_arg0 = data.readString()!!
mDynamicPluginLoader.loadPlugin(_arg0)
reply!!.writeNoException()
try {
mDynamicPluginLoader.loadPlugin(_arg0)
reply.writeNoException()
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
return true
}
PluginLoader.TRANSACTION_getLoadedPlugin -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _result = mDynamicPluginLoader.getLoadedPlugin()
reply!!.writeNoException()
reply.writeMap(_result as Map<*, *>?)
try {
val _result = mDynamicPluginLoader.getLoadedPlugin()
reply.writeNoException()
reply.writeMap(_result as Map<*, *>?)
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}

return true
}
PluginLoader.TRANSACTION_callApplicationOnCreate -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _arg0: String
_arg0 = data.readString()!!
mDynamicPluginLoader.callApplicationOnCreate(_arg0)
reply!!.writeNoException()
try {
mDynamicPluginLoader.callApplicationOnCreate(_arg0)
reply.writeNoException()
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}

return true
}
PluginLoader.TRANSACTION_convertActivityIntent -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _arg0: android.content.Intent?
if (0 != data.readInt()) {
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
val intent = if (0 != data.readInt()) {
Intent.CREATOR.createFromParcel(data)
} else {
_arg0 = null
reply.writeException(NullPointerException("intent==null"))
return true
}
val _result =
mDynamicPluginLoader.convertActivityIntent(_arg0!!)//todo #32 去掉这个不安全的!!
reply!!.writeNoException()
if (_result != null) {
reply.writeInt(1)
_result.writeToParcel(
reply,
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
)
} else {
reply.writeInt(0)

try {
val _result =
mDynamicPluginLoader.convertActivityIntent(intent)
reply.writeNoException()
if (_result != null) {
reply.writeInt(1)
_result.writeToParcel(
reply,
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
)
} else {
reply.writeInt(0)
}
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
return true
}
PluginLoader.TRANSACTION_startPluginService -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _arg0: android.content.Intent?
if (0 != data.readInt()) {
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
val intent = if (0 != data.readInt()) {
Intent.CREATOR.createFromParcel(data)
} else {
_arg0 = null
reply.writeException(NullPointerException("intent==null"))
return true
}
val _result = mDynamicPluginLoader.startPluginService(_arg0!!)//todo #32 去掉这个不安全的!!
reply!!.writeNoException()
if (_result != null) {
reply.writeInt(1)
_result.writeToParcel(
reply,
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
)
} else {
reply.writeInt(0)

try {
val _result = mDynamicPluginLoader.startPluginService(intent)
reply.writeNoException()
if (_result != null) {
reply.writeInt(1)
_result.writeToParcel(
reply,
android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE
)
} else {
reply.writeInt(0)
}
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
return true
}
PluginLoader.TRANSACTION_stopPluginService -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _arg0: android.content.Intent?
if (0 != data.readInt()) {
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
val intent = if (0 != data.readInt()) {
Intent.CREATOR.createFromParcel(data)
} else {
_arg0 = null
reply.writeException(NullPointerException("intent==null"))
return true
}
try {
val _result = mDynamicPluginLoader.stopPluginService(intent)
reply.writeNoException()
reply.writeInt(if (_result) 1 else 0)
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
val _result = mDynamicPluginLoader.stopPluginService(_arg0!!)//todo #32 去掉这个不安全的!!
reply!!.writeNoException()
reply.writeInt(if (_result) 1 else 0)
return true
}
PluginLoader.TRANSACTION_bindPluginService -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
val _arg0: android.content.Intent?
if (0 != data.readInt()) {
_arg0 = android.content.Intent.CREATOR.createFromParcel(data)
val intent = if (0 != data.readInt()) {
Intent.CREATOR.createFromParcel(data)
} else {
_arg0 = null
reply.writeException(NullPointerException("intent==null"))
return true
}
val _arg1 = BinderPluginServiceConnection(data.readStrongBinder())
val _arg2: Int
_arg2 = data.readInt()
val _result = mDynamicPluginLoader.bindPluginService(
_arg0!!,
_arg1,
_arg2
)//todo #32 去掉这个不安全的!!
reply!!.writeNoException()
reply.writeInt(if (_result) 1 else 0)
try {
val _result = mDynamicPluginLoader.bindPluginService(
intent,
_arg1,
_arg2
)
reply.writeNoException()
reply.writeInt(if (_result) 1 else 0)
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
return true
}
PluginLoader.TRANSACTION_unbindService -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
mDynamicPluginLoader.unbindService(data.readStrongBinder())
reply!!.writeNoException()
try {
mDynamicPluginLoader.unbindService(data.readStrongBinder())
reply.writeNoException()
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
return true
}
PluginLoader.TRANSACTION_startActivityInPluginProcess -> {
data.enforceInterface(PluginLoader.DESCRIPTOR)
mDynamicPluginLoader.startActivityInPluginProcess(
Intent.CREATOR.createFromParcel(
data
try {
mDynamicPluginLoader.startActivityInPluginProcess(
Intent.CREATOR.createFromParcel(
data
)
)
)
reply!!.writeNoException()
reply.writeNoException()
} catch (e: Exception) {
reply.writeException(wrapExceptionForBinder(e))
}
return true
}
}
return super.onTransact(code, data, reply, flags)
}

/**
* Binder的内置writeException方法只支持特定几种Exception
* https://developer.android.com/reference/android/os/Parcel.html#writeException(java.lang.Exception)
*/
private fun wrapExceptionForBinder(e: Exception): Exception {
return IllegalStateException(e.message, e.cause)
}

}

0 comments on commit d26ced6

Please sign in to comment.