我在kotlin扩展文件中具有此功能以传递方法,但是它不起作用。请解释一下它的正确制作方法,请尝试以下方法:
fun showErrorClientScreen(context: Context, action : () -> Unit) {
val intent = Intent(context, RestClientErrorActivity::class.java)
val bundle = Bundle()
bundle.putSerializable(UPDATE_CLIENT_ERROR, ErrorClientListener { action })
intent.putExtra(UPDATE_CLIENT_ERROR_BUNDLE, bundle)
context.startActivity(intent)
}
使用Java接口
public interface ErrorClientListener extends Serializable {
void tryAgainFunction();
}
以及我需要监听的活动单击按钮,然后重试发送请求:
class RestClientErrorActivity: BaseActivity(), View.OnClickListener {
private lateinit var errorClientListener: ErrorClientListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_rest_client_error)
try {
val bundle = intent.getBundleExtra(UPDATE_CLIENT_ERROR_BUNDLE)
errorClientListener = bundle?.getSerializable(UPDATE_CLIENT_ERROR) as ErrorClientListener
} catch (e: Exception) {
e.message
}
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.ib_update -> errorClientListener.tryAgainFunction()
}
}
}
答案 0 :(得分:1)
在活动之间打包interfaces
是很奇怪的,绝对是不可取的。它可能未在Activity A
和Activity B
之间进行序列化的原因之一是因为该对象是在Activity A
中创建的,它被视为匿名类创建,并且Activity A
持有对这个对象,因此防止它被序列化。这很好,因为您可以在接口回调中创建对对象的引用,而这些引用又将通过实例化它的类保留。因此,垃圾收集器将无法在这些对象上运行收集并释放空间。导致大量内存泄漏。
解决问题的另一种方法可能是使用干净的体系结构和Singleton
类模式,这两种活动都可以访问它们,并且只说一次Activity A
即可实例化一次:
class SingletonErrorHandler private constructor(){
var isError = false
fun doOnError() {
// do non view related stuff
// like a network call or something
}
companion object {
val instance by lazy { SingletonErrorHandler() }
}
}
在您可以定义的活动中
class ActivityA : AppCompatActivity() {
fun onError() {
SingletonErrorHandler.instance.isError = true
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.a_activity)
}
}
活动B
class ActivityB : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.b_activity)
val errorHandler = SingletonErrorHandler.instance
if(errorHandler.isError)
errorHandler.doOnError()
}
}
答案 1 :(得分:0)
我有同样的问题。如HawkPriest's Answer中所述,您的对象不可序列化,因为它是一个匿名类。解决此问题的另一种方法是简单地实现一个实现您的接口的非匿名类。这是我的代码:
界面
class MyClass : MyInterface {
override fun instruction() {
// does something
}
}
课程
val myObject = MyClass()
val intent = Intent(context, MyActivity::class.java).putExtra("Tag", myObject)
context.startActivity(intent)
通话活动
override fun onCreate(savedInstanceState: Bundle?) {
val myObject = intent.getSerializableExtra("Tag") as MyInterface
myObject.instruction()
}
活动
instruction
关于评论中提到的“本机资源”,您可以使MyObject
接受参数或将其传递给val projection = arrayOf(
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.MediaColumns.RELATIVE_PATH
)
val path = "Pictures/$folderName"
val name = fileName
val selection = MediaStore.Files.FileColumns.RELATIVE_PATH + " like ? and "+ MediaStore.Files.FileColumns.DISPLAY_NAME + " like ?"
val selectionargs = arrayOf("%" + path + "%", "%" + name + "%")
val cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionargs, null);
val indexDisplayName = cursor?.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME)
if(cursor!!.count > 0){
// file is exist
}
// or you can see displayName
while (cursor!!.moveToNext()) {
val displayName = indexDisplayName?.let { cursor.getString(it) }
}
。
P.S。 Singleton解决方案存在的问题:
答案 2 :(得分:0)
您可以编写工厂方法来启动活动,就像android studio为片段创建生成工厂方法一样。
class RestClientErrorActivity : AppCompatActivity() {
companion object {
private var completion: (() -> Unit)? = null
fun start(context: Context, completion: (() -> Unit)?) {
RestClientErrorActivity.completion = completion
val bundle = Bundle()
intent.putExtra(UPDATE_CLIENT_ERROR_BUNDLE, bundle)
context.startActivity(intent)
}
}
private lateinit var retryButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retryButton = findViewById(R.id.btn_retry)
}
fun onRetryClick(view: View) {
finish()
completion?.invoke()
}
}
注意:完成不是强制性的。所以我将其设置为可为空。如果您在不使用工厂方法的情况下启动活动,应用程序将不会崩溃。