2011-09-28 47 views
35

Đây là mã của tôi:Android, AsyncTask, hãy kiểm tra trạng thái?

Trong onCreate:

new LoadMusicInBackground().execute(); 

Sau đó, vào cuối lớp học chính của tôi, tôi có mã này

/** Helper class to load all the music in the background. */ 
class LoadMusicInBackground extends AsyncTask<Void, String, Void> { 
    @Override 
    protected Void doInBackground(Void... unused) { 

     soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 100); 
     soundPoolMap = new HashMap<Integer, Integer>(); 

     soundPoolMap.put(A1, 
       soundPool.load(GameScreen_bugfix.this, R.raw.a, 1)); 
     soundPoolMap.put(A3, 
       soundPool.load(GameScreen_bugfix.this, R.raw.b, 1)); 
     soundPoolMap.put(A5, 
       soundPool.load(GameScreen_bugfix.this, R.raw.c_s, 1)); 
     soundPoolMap.put(A6, 
       soundPool.load(GameScreen_bugfix.this, R.raw.d, 1)); 
     soundPoolMap.put(A8, 
       soundPool.load(GameScreen_bugfix.this, R.raw.e, 1)); 
     soundPoolMap.put(A10, 
       soundPool.load(GameScreen_bugfix.this, R.raw.f_s, 1)); 
     soundPoolMap.put(A12, 
       soundPool.load(GameScreen_bugfix.this, R.raw.g_s, 1)); 
     soundPoolMap.put(wrong, 
       soundPool.load(GameScreen_bugfix.this, R.raw.wrong2, 1)); 

     publishProgress(""); 
     Log.v("SOUNDPOOL", "" + soundPoolMap); 
     return (null); 
    } 

    @Override 
    protected void onProgressUpdate(String... item) { 
     // text1.setText(item[0]); 
    } 

    @Override 
    protected void onPostExecute(Void unused) { 
     //Toast.makeText(GameScreen_bugfix.this, "music loaded!", Toast.LENGTH_SHORT).show(); 
    } 
} 

Nếu âm nhạc đã không được nạp Tôi nhận được một nullpointer ngoại lệ, nhìn vào các tài liệu tôi thấy có một getStatus() nhưng tôi đã thử một cái gì đó như thế này:

music_load_status=LoadMusicInBackground.getStatus() 

và điều đó không hoạt động: ( Làm cách nào để kiểm tra xem tác vụ nền đã hoàn thành chưa và nhạc đã được tải chưa?

Cảm ơn!
Ryan

Trả lời

156

getStatus() kiểm tra xem AsyncTask đang chờ xử lý, đang chạy hay đã hoàn tất.

LoadMusicInBackground lmib = new LoadMusicInBackground(); 

if(lmib.getStatus() == AsyncTask.Status.PENDING){ 
    // My AsyncTask has not started yet 
} 

if(lmib.getStatus() == AsyncTask.Status.RUNNING){ 
    // My AsyncTask is currently doing work in doInBackground() 
} 

if(lmib.getStatus() == AsyncTask.Status.FINISHED){ 
    // My AsyncTask is done and onPostExecute was called 
} 

Nếu bạn muốn kiểm tra xem hành động của bạn có thực sự thành công hay không (nghĩa là nhạc đã được tải thành công), bạn cần phải đưa ra phương pháp xác định điều đó. getStatus() chỉ có thể xác định trạng thái của chuỗi thực tế trong AsyncTask.

+0

Cảm ơn! Sẽ kiểm tra xem nó ra! – Ryan

+11

Để làm rõ: HOÀN THÀNH là trạng thái SAU onPostExecute được gọi. Nếu bạn kiểm tra trạng thái thời gian trênPostExecute trạng thái sẽ được RUNNING – user123321

+0

thì tại sao nó trở lại RUNNING sau khi postexcute, bit của nó đáng ngạc nhiên – Sameer

17

Đây là chương trình không đồng bộ - bạn không nên kiểm tra từ chuỗi giao diện người dùng, vì điều này có nghĩa là bạn đang chặn luồng giao diện người dùng (có thể chạy vòng lặp kiểm tra bằng Thread.sleep()?).

Thay vào đó bạn sẽ được gọi khi AsyncTask được thực hiện: từ số onPostExecute() gọi bất kỳ phương thức nào trong Hoạt động bạn cần.

Lưu ý: nhược điểm của phương pháp này là Hoạt động phải được kích hoạt khi chuỗi nền kết thúc. Điều này thường không phải là trường hợp, ví dụ nếu quay lại là prwssed hoặc định hướng được thay đổi. Cách tiếp cận tốt hơn là gửi một chương trình phát sóng từ onPostExecute() và sau đó các hoạt động quan tâm có thể đăng ký để nhận nó. Phần tốt nhất là Activity chỉ nhận được phát sóng nếu nó hoạt động tại thời điểm đó, có nghĩa là nhiều Hoạt động có thể đăng ký, nhưng chỉ một hoạt động sẽ nhận được nó.

2

Tạo AsyncTask với người nghe

class ClearSpTask extends AsyncTask<Void, Void, Void> { 

    public interface AsynResponse { 
     void processFinish(Boolean output); 
    } 

    AsynResponse asynResponse = null; 

    public ClearSpTask(AsynResponse asynResponse) { 
     this.asynResponse = asynResponse; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     showProgressDialog(); 
    } 

    @Override 
    protected Void doInBackground(Void... voids) { 
     cleardata(); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     hideProgressDialog(); 
     asynResponse.processFinish(true); 
    } 
} 

Và sử dụng AsyncTask

new ClearSpTask(new ClearSpTask.AsynResponse() { 
     @Override 
     public void processFinish(Boolean output) { 
      // you can go here 
     } 
}).execute(); 

Tôi hy vọng điều này có thể giúp một số người

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