2017-06-27 12 views
7

Có rất nhiều câu hỏi ở đây đối phó với This class should be static or leaks might occur trong java android.Cách tiếp cận phù hợp với "Lớp AsyncTask này nên tĩnh hoặc rò rỉ có thể xảy ra" trong Kotlin Android là gì?

This Handler class should be static or leaks might occur: IncomingHandler

This Handler class should be static or leaks might occur:AsyncQueryHandler

This AsyncTask class should be static or leaks might occur (anonymous android.os.AsyncTask)

Cảnh báo là do thực tế rằng lớp bên trong chứa một tham chiếu ngầm với lớp bên ngoài, và do đó ngăn ngừa các lớp bên ngoài từ GC'd. Giải pháp nằm trong chính cảnh báo rằng lớp phải được khai báo là tĩnh.

Tuy nhiên, giải pháp là đặc trưng cho java. Do kotlin không có công cụ sửa đổi static, điều gần nhất là companion object và đối tượng đồng hành giữ tham chiếu đến nó là "lớp bên ngoài".

Dưới đây là của tôi [thất bại] cố gắng với những nhận xét

class MyActivity : AppCompatActivity(), MyListener { 

    companion object { 
     class Attempt3Task(val callback: MyListener) : AsyncTask<Unit, Unit, Unit>() { 
      override fun doInBackground(vararg params: Unit?) { 
       TODO("") 
      } 

      override fun onPostExecute(result: Unit?) { 
       callback.updateUi() 
      } 
     } 
    } 

    inner class Attempt2Task : AsyncTask<Unit, Unit, Unit>() { 
     override fun doInBackground(vararg params: Unit?) { 
      TODO(" 
     } 
    } 

    // Gives warning "This AsyncTask class should be static or leaks might occur" 
    val attempt_1 = object: AsyncTask<Unit, Unit, Unit>() { 
     override fun doInBackground(vararg params: Unit?) { 
      TODO("") 
     } 
    } 

    // Does not give warning but, as far as I can tell, is conceptually same as attempt_1 
    val attempt_2 = Attempt2Task() 

    // Does not give warning but companion object does have reference to the activity, no? 
    val attempt_3 = Attempt3Task(this) 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
    } 
} 

Are sự khẳng định về attempt2 và attempt3 đúng khi cho rằng ngay cả khi không cảnh báo Linter, mã vẫn bị rò rỉ?

Chúng tôi phải làm gì để tránh bị rò rỉ? Tôi có nên giải quyết ở cấp cao nhất cũ class MyTask : AsyncTask<Unit, Unit, Unit>() với thành viên WeakReference để gọi lại không?

+0

Tôi muốn nói 'AsyncTask 'nên càng địa phương càng tốt. vì vậy tất cả các mã ở trên là sử dụng sai. có nghĩa là vứt bỏ/giải phóng nó ngay lập tức sau khi sử dụng. –

+0

Các lớp lồng nhau trong Kotlin tương đương với 'lớp tĩnh' trong Java theo mặc định - bạn có thử bỏ từ khóa' inner' của 'Attempt2Task' không? Xem https://kotlinlang.org/docs/reference/nested-classes.html –

+0

@JK Cảm ơn bạn đã chỉ ra! Tôi đã đọc phần 'inner classes' nhiều lần mà không nhận ra nó được ngụ ý rằng các lớp lồng nhau không có quyền truy cập vào thành viên của lớp bên ngoài! – user2829759

Trả lời

1

Tại sao bạn không có khai báo lớp AsyncTask bên ngoài lớp hoạt động?

Trong Kotlin có thể ở cùng một tệp với hoạt động nhưng ngay trên/dưới lớp Hoạt động.

Bằng cách đó không có vấn đề gì về tham chiếu bị ẩn.

Cũng đảm bảo chỉ giữ một WeakReference cho người nghe bên trong AsyncTask của bạn.

Điều đó nói rằng, theo tôi, AsyncTask thuộc về quá khứ, và bây giờ bạn nên sử dụng một số giải pháp thay thế hiện đại hơn như RxJava, đồng thói quen, Máy bốc hàng, vv

Các vấn đề liên quan