2012-04-10 73 views
2

我有一个处理程序注册在一个活动。 handleMessage()在适配器上调用notifyDataSetChanged。事情最初的重点在于事情的工作。但是,当我离开Activity并返回时,notifyDataSetChanged()不起作用。处理程序调用notifyDataSetChanged()不执行

FileAdapter是一个ArrayAdapter。 MergeAdapter是CommonsWare的一个自定义类。 _mergeAdapter包含_fileAdapter。

活动码:

public void setUpDownloadHandler() { 
// Define the Handler that receives messages from the thread and update the progress 
_downloadHandler = new Handler() { 
    public void handleMessage(Message message) { 
     super.handleMessage(message); 
     String fileId = (String) message.obj; 
     int progress = message.arg1; 
     FileInfo tempFile = null; 
     for (FileInfo file: _files) { 
    if (file.getFileId().equals(fileId)) { 
        file.setDownloadProgress(progress); 
        tempFile = file; 
       } 
      } 
      if (tempFile != null) { 
       _files.remove(tempFile); 
       _files.add(tempFile); 
      } 
      _fileAdapter.notifyDataSetChanged(); 
      _mergeAdapter.notifyDataSetChanged(); 
     } 
    }; 
} 

跑过处理程序:

RunnableTask task = new DownloadFileRunnableImpl(application, the_workspace_url, the_file_info, the_workspace_info.getTitle(), the_internal_storage_directory, 
       _downloadHandler); 

后台线程代码:

if(temp > previous) { 
    Message message = new Message(); 
    message.arg1 = _currentProgress.intValue(); 
    message.obj = _fileId; 
    _progressHandler.sendMessage(message); 
    previous = temp; 
} 

的另一条信息是我传递该处理程序通过一个活页夹,然后进入可运行。我这样做是为了在Service中运行后台线程。我不认为这是问题。

编辑: 好像处理程序不与活动相关联的是导航到(也许是因为的onCreate创建一个新的处理程序)的第二次。有没有办法重新关联或保留旧的处理程序?

更新 该活动正在被销毁,当它失去焦点到另一个活动。

回答

1

我会尝试在您的活动的onDestroy方法中放置一条日志消息,以查看它是否在您的活动离开时被破坏。所以你的任务可能有旧活动的处理程序。

+0

确定。如果处理程序被销毁,它会不会丢失与后台线程的连接,而不会更新新的活动? – benkdev 2012-04-10 18:07:55

+0

这就是我认为正在发生的事情。这可能也是别的,这就是为什么我认为你应该检查日志消息。或者你可以在调试模式下运行它,并在活动的onDestroy中放置一下,看看它是否被调用。 – flobacca 2012-04-10 18:14:07

+0

我检查并且当我离开它时,活动不会被破坏。当我重新导航时,它会在onCreate()中创建一个新的处理程序。 – benkdev 2012-04-10 18:27:28

0

这里是我的回答,我主要依靠http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.html

真的只是把自己的代码,并改变它,这样我不得不重拍的片段,每次我想重新开始线程(工作)。它通过处理程序与活动进行通信。

public class Main extends Activity implements WorkProgressListener { 

private static final String TAG = "tag"; 

private Handler handler; 

private Button startWorkBtn; 

private ProgressDialog progressDialog; 

private boolean onSaveInstanceFlag = false; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.i(TAG,"Main onCreate " + Utils.getThreadId()); 

    setContentView(R.layout.main); 

    handler = new ProgressHandler(); 

    startWorkBtn = (Button)this.findViewById(R.id.start_work_btn); 
    startWorkBtn.setEnabled(false); 
    startWorkBtn.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick (View v) { 
     Log.i("tag","Main: startWorkBtn onClick "); 
     startWorkBtn.setEnabled(false); 
     FragmentManager fm = getFragmentManager(); 
     Fragment workF = (Fragment)fm.findFragmentByTag("work"); 
     if (null == workF) { 
      workF = new WorkFragment(); 
      Log.i(TAG,"Main new WorkF" + Utils.getThreadId()); 

      startProgressDialog(true); 
      startWorkBtn.setEnabled(false); 
      fm.beginTransaction().add(workF, "work").commit(); 
      Log.i(TAG,"Main add(workF) " + Utils.getThreadId()); 

     } 
     else { 
      // should never be able to get here. 
     }    
    }   
}); 

    FragmentManager fm = getFragmentManager(); 

    Fragment loadingFragment = fm.findFragmentByTag("work"); 
    Log.i(TAG,"Main findFragment " + Utils.getThreadId()); 

    if (null == loadingFragment) { 
     this.startWorkBtn.setEnabled(true); 
    } 
    else { 
     // could also decide to show progress dialog based on savedInstanceState 
     this.startProgressDialog(true); 
    } 

} // end onCreate 

@Override 
public void onRestart() { 
    Log.i(TAG,"Main onRestart " + Utils.getThreadId()); 
    super.onRestart(); 
    this.onSaveInstanceFlag = false; 
} 


@Override 
public void onResume() { 
    Log.i(TAG,"Main onResume " + Utils.getThreadId()); 
    super.onResume(); 
    this.onSaveInstanceFlag = false; 
} 


@Override 
public void onSaveInstanceState (Bundle savedInstanceState) { 
    Log.i(TAG,"Main onSaveInstanceState "+ Utils.getThreadId()); 

    this.onSaveInstanceFlag = true; 

    super.onSaveInstanceState(savedInstanceState); 
    if (null != this.progressDialog) { 
     savedInstanceState.putBoolean("progressDialog", true); 
    } 
    else { 
     savedInstanceState.putBoolean("progressDialog", false); 
    } 
} 

@Override 
public void onStop() { 
    Log.i(TAG,"Main onStop " + Utils.getThreadId()); 
    super.onStop(); 
} 

@Override 
public void onDestroy() { 
    Log.i(TAG,"Main onDestroy " + Utils.getThreadId());  
    super.onDestroy(); 
    this.closeProgressDialog(); 
    this.handler.removeCallbacksAndMessages(null); 
} 


public class ProgressHandler extends Handler { 

    @Override 
    public void handleMessage (Message msg) { 
     Log.i(TAG,"Main ProgressDialogHandler handleMessage"); 
     Bundle b = msg.getData();   
     boolean isDone = b.getBoolean("isDone"); 
     String tag = b.getString("tag"); 

     if (isDone && !onSaveInstanceFlag) { 
      FragmentManager fm = getFragmentManager(); 
      Fragment loader = (Fragment)fm.findFragmentByTag(tag); 

      fm.beginTransaction().remove(loader).commit(); 

      closeProgressDialog(); 
      Main.this.startWorkBtn.setEnabled(true); 
     } 
    }  
} 


@Override 
public void sendProgress(String tag, int progress, int max) { 
    if (progress == max) { 
     Log.i(TAG,"Main sendProgress " + Utils.getThreadId()); 
     Message message = handler.obtainMessage();   
     Bundle b = new Bundle(); 
     b.putBoolean("isDone", true); 
     b.putString("tag",tag); 
     message.setData(b); 
     this.handler.sendMessage(message); 
    }  

} 

private void startProgressDialog(boolean show) { 
    this.progressDialog = new ProgressDialog(this); 
    this.progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
    this.progressDialog.setMessage("loading"); 
    this.progressDialog.setCancelable(false); 
    this.progressDialog.show(); 
} 

private void closeProgressDialog() { 
    if (null != this.progressDialog) { 
     progressDialog.cancel(); 
     this.progressDialog = null; 
    }  
} 

} // end Main 

公共类WorkFragment延伸片段{

private static final String TAG = "tag"; 

private boolean mReady = false; 
private boolean mQuiting = false; 

private boolean done = false; 

public WorkFragment() {} 

final Thread mThread = new Thread() { 
    @Override 
    public void run() { 

    synchronized(this) { 
      while (!mReady) { 
       Log.i(TAG,"WorkF notReady"+ Utils.getThreadId());    

       if (mQuiting) { 
        return; 
       } 
       try { 
        wait(); 
       } catch (InterruptedException e) { 
       } 
      } 
     } // end synchronized 


     Log.i(TAG,"WorkF starting work "+ Utils.getThreadId());    

     try { 
      Log.i(TAG,"WorkF about to sleep"+ Utils.getThreadId());    

      Thread.currentThread().sleep(10000l); 

      Log.i(TAG,"WorkF almost finished "+ Utils.getThreadId());    

      done = true; 

     } catch (InterruptedException e1) { 
      e1.printStackTrace(); 
     } 

     synchronized(this) { 
      while (!mReady) { 
       Log.i(TAG,"Activity notReady"+ Utils.getThreadId());     

       if (mQuiting) { 
        return; 
       } 
       try { 
        wait(); 
       } catch (InterruptedException e) { 
       } 
      } 

      ((WorkProgressListener)getActivity()).sendProgress(WorkFragment.this.getTag(), 100, 100); 

     } // end synchronized 2 
    } 

}; 


@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    Log.i(TAG,"WorkF, onAttach: "+ Utils.getThreadId()); 

} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.i(TAG,"WorkF, onCreate: "+ Utils.getThreadId()); 

    setRetainInstance(true); 

    mThread.start(); 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    Log.i(TAG,"WorkF, onActivityCreated: "+ Utils.getThreadId()); 

    if (done) { 
     ((WorkProgressListener)getActivity()).sendProgress(WorkFragment.this.getTag(), 100, 100); 
    } 

    synchronized (mThread) { 
     mReady = true; 
     mThread.notify(); 
    } 
} 

@Override 
public void onStart() 
{ 
    super.onStart(); 
    Log.i(TAG,"WorkF, onStart: "+ Utils.getThreadId()); 

} 

@Override 
public void onDestroy() { 
    synchronized (mThread) { 
     mReady = false; 
     mQuiting = true; 
     mThread.notify(); 
    } 

    super.onDestroy(); 
} 

@Override 
public void onDetach() { 
    synchronized (mThread) { 
     mReady = false; 
     mThread.notify(); 
    } 

    super.onDetach(); 
} 

public void restart() { 
    synchronized (mThread) { 
     mThread.notify(); 
    } 
} 
}// end WorkFragment 

public interface WorkProgressListener { 

public void sendProgress (String tag, int progress, int max); 

} 
+0

将第二个同步工作语句从for循环更改为if语句,以便在创建新活动时线程不会等待至无穷大。 if(null!= WorkFragment.this){if(mReady){((WorkProgressListener).getActivity())。sendProgress(....):}} – flobacca 2012-04-20 16:34:24

+0

oops- rewrite“因此,如果没有创建新的活动线程没有等到无限远“ – flobacca 2012-04-30 19:26:11