nhận ngữ cảnh trong AsyncTask


83

Tôi đang cố gắng lấy ngữ cảnh trong AsyncTask của mình thuộc lớp có tên là Opciones (lớp này là lớp duy nhất gọi tác vụ đó) nhưng tôi không biết làm thế nào để thực hiện, tôi đã thấy một số mã như sau:

      protected void onPostExecute(Long result) {

    Toast.makeText(Opciones.this,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
}

Nhưng nó không hoạt động với tôi nó nói: "No enclosing instance of the type Opciones in scope"


4
Opciones có phải là một hoạt động không? Nếu không, bạn cần phải vượt qua một bối cảnh vào lớp đó và sau đó sử dụng trongAsyncTask
Torben Kohlmeier

Điều này trông giống như một câu trả lời stackoverflow.com/questions/45653121/…
Mangesh,

Câu trả lời:


176

Bạn cần làm những điều sau đây.

  • khi bạn muốn sử dụng AsyncTask , hãy mở rộng điều đó trong lớp khác, nói MyCustomTask .
  • trong phương thức khởi tạo của lớp mới, truyền Context

Thí dụ

public class MyCustomTask extends AsyncTask<Void, Void, Long> {

    private Context mContext;

    public MyCustomTask (Context context){
         mContext = context;
    }

    //other methods like onPreExecute etc.
    protected void onPostExecute(Long result) {
         Toast.makeText(mContext,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
    }
}

Và khởi tạo lớp bằng cách làm theo.

MyCustomTask task = new MyCustomTask(context);
task.execute(..);

36
lưu ý rằng sẽ là tốt hơn rất nhiều để sử dụng lớp không lồng nhau hoặc tĩnh và giữ mContext trong một WeakReference để tránh rò rỉ bộ nhớ
BamsBamx

8
Giữ bối cảnh trong cảnh báo tĩnh bộ nhớ lớp ném rò rỉ lồng nhau
Amir Hossein Ghasemi

2
và cũng giữ lớp không tĩnh trong lớp lồng nhau gây ra cảnh báo rò rỉ bộ nhớ toàn lớp! vậy chúng ta nên sử dụng ngữ cảnh gì mà không bị rò rỉ bộ nhớ !?
Amir Hossein Ghasemi

1
Tìm cách giải quyết rò rỉ bộ nhớ, Ngữ cảnh phải là một lớp WeakReference.
Amir Hossein Ghasemi

Đây sẽ không phải là lớp tĩnh lồng nhau. Lớp công khai của nó và cần được xác định hoạt động sau đó riêng biệt. Nhưng có, để an toàn hơn, chúng ta có thể sử dụng WeakReference.
Chintan Rathod

59

Giữ một tham chiếu yếu cho Activity của máy chủ sẽ ngăn chặn rò rỉ bộ nhớ.

static class MyTask extends AsyncTask<Void, Void, Void> {
    // Weak references will still allow the Activity to be garbage-collected
    private final WeakReference<Activity> weakActivity;

    MyTask(Activity myActivity) {
      this.weakActivity = new WeakReference<>(myActivity);
    }

    @Override
    public Void doInBackground(Void... params) {
      // do async stuff here
    }

    @Override
    public void onPostExecute(Void result) {
      // Re-acquire a strong reference to the activity, and verify
      // that it still exists and is active.
      Activity activity = weakActivity.get();
      if (activity == null
          || activity.isFinishing()
          || activity.isDestroyed()) {
        // activity is no longer valid, don't do anything!
        return;
      }

      // The activity is still valid, do main-thread stuff here
    }
  }

1
Còn khi chúng ta chuyển đổi giữa các hoạt động (dừng và tiếp tục asyntask), và sau đó quay lại, Yếu tố vẫn hoạt động?
D4rWiNS

1
Có lợi ích gì khi truyền yếu tố tham khảo cho lớp thay vì chuyển myActivity không?
seekingStillness

1
@seekingStillness Các tham chiếu yếu sẽ vẫn cho phép Hoạt động được thu thập rác, do đó ngăn chặn rò rỉ bộ nhớ.
Sai

13

Vì chỉ một người Activitysử dụng tác vụ này nên chỉ cần đặt nó trở thành một lớp bên trong của nóActivity

public class Opciones extends Activity
{
     public void onCreate()
     {
         ...
     }

    public class MyTask extends AsyncTask<>
    {
        ...

         protected void onPostExecute(Long result) {
        Toast.makeText(Opciones.this,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
     }
}

Sau đó, bạn có quyền truy cập vào các biến thành viên của ActivityContext


2
Lint hiển thị cảnh báo về rò rỉ bộ nhớ nếu lớp AsyncTask không tĩnh.
SapuSeven

@SapuSeven Hãy nhớ rằng đó chỉ là một cảnh báo . Cá nhân tôi không nghĩ rằng nó sẽ là một vấn đề nếu được sử dụng đúng cách như AsyncTaskđối với các hoạt động tồn tại trong thời gian ngắn và thường để cập nhật các chế độ xem trong một Activity. Thông thường, bạn nên hủy bỏ chúng onPause()nếu chúng vẫn đang chạy. Có lẽ tôi sai nhưng đó luôn là suy nghĩ của tôi về nó. Đây là một số bài đọc thêm về chủ đề này .
codeMagic, 07/07/17

-6

Bạn có thể viết getApplicationContex(). Hoặc Xác định biến toàn cục.

Activity activity;

Và tại onCreate()chức năng

activity = this;

sau đó,

 protected void onPostExecute(Long result) {

    Toast.makeText(activity,"Subiendo la foto. ¡Tras ser moderada empezara a ser votada!: ", Toast.LENGTH_LONG).show(); 
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.