android - How should I share Activity related code between multiple activities?
问题描述
I have several bits of functionality that I need in multiple activities in my app. They need to be able to access Activity methods, and in some cases override methods (e.g. I have some shared functionality to choose pictures from the Gallery that needs to handle onRequestPermissionsResult
).
Any one of these is simple - I can create a XXXBase class, and then my Activity can derive from it. If I need more than one of these in my Activity though, I am limited by inheritance mechanics.
I could put all of this extra functionality in one common Base class that is used repeatedly, but that class could end up getting quite big and unwieldy.
Is there an alternative approach that I'm missing? I'm using Kotlin, if that opens up any extra possibilities.
解决方案
Given that you need to override certain framework methods, I think this actually would be a great case for using a headless Fragment
. Using a Fragment
, you can start Activity
s, request permissions, handle the results, etc. Using this pattern, this Fragment
can be attached to any Activity
(or even another Fragment
as a child). You of course could break down further classes that this headless Fragment
relies on internally, but I would definitely suggest looking into a Fragment
-based approach.
For example:
private const val REQUEST_CODE_PERMISSION: Int = 1
class MyUtilityFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
if (savedInstanceState == null) {
// do permission request
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
): {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
// handle your permission result here
}
}
Then in your Activity
, you can just attach it in onCreate()
and let it do its thing:
class MyActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.add(MyUtilityFragment(), "utility_fragment")
.commitNow()
}
}
}
If you need to provide results back to the host, you can just designate an interface in your Fragment
, and have the hosting parent Fragment
or Activity
implement that interface, and then retrieve it from the headless Fragment
when needed:
private fun getCallback() : MyCallbackInterface {
parentFragment?.takeIf { it is MyCallbackInterface }?.let { return it as MyCallbackInterface }
return requireActivity() as MyCallbackInterface
}
推荐阅读
- javascript - 向 windows.location 添加了参数,现在页面不想重定向到所需的表单
- python - 如何让 python 编程持续运行
- c# - 连接特定无线显示设备的程序
- r - 如何计算 R 中的最大 8 小时移动(滚动)平均值?
- .net - 下载器应用程序 .NET 中的未知问题
- asp.net-mvc - 如何在我的 MVC 编辑器模板中干燥代码?
- servicestack - 撤销承载令牌和刷新令牌 - ServiceStack
- bash - 用于 gzip 特定文件扩展名的 Bash 脚本
- javascript - ReactJS - 组件之外的全局状态
- c# - 等效命令或单行代码,如 C# 中 unix 中的 mget 命令