Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 对notifyDataSetChanged()的处理程序调用未执行_Android_Multithreading_Listview_Handler_Adapter - Fatal编程技术网

Android 对notifyDataSetChanged()的处理程序调用未执行

Android 对notifyDataSetChanged()的处理程序调用未执行,android,multithreading,listview,handler,adapter,Android,Multithreading,Listview,Handler,Adapter,我在活动中注册了一个处理程序。handleMessage()调用适配器上的notifyDataSetChanged。当活动具有初始焦点时,事情就会起作用。但是,当我离开活动并返回时,notifyDataSetChanged()不起作用 FileAdapter是一个ArrayAdapter。MergeAdapter是Commonware提供的自定义类_mergeAdapter包含_fileAdapter 活动代码: public void setUpDownloadHandler() { //

我在活动中注册了一个处理程序。handleMessage()调用适配器上的notifyDataSetChanged。当活动具有初始焦点时,事情就会起作用。但是,当我离开活动并返回时,notifyDataSetChanged()不起作用

FileAdapter是一个ArrayAdapter。MergeAdapter是Commonware提供的自定义类_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;
}
另一条信息是,我将处理程序通过一个活页夹传递给runnable。我这样做是为了在服务中运行后台线程。我认为这不是问题所在

编辑: 第二次导航到该处理程序时,它似乎与该活动没有关联(可能是因为onCreate创建了一个新的处理程序)。有没有办法重新关联或保留旧的处理程序

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

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

这是我的答案,我非常依赖它

实际上,我只是利用了他们的代码并对其进行了更改,这样每当我想再次启动线程(工作)时,我都必须重新生成片段。它通过处理程序与活动进行通信

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
公共类工作片段扩展了该片段{

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);

}

好的。如果处理程序被销毁了,它会不会失去与后台线程的连接,而不会更新新活动?我认为这就是正在发生的事情。但也可能是其他原因,这就是为什么我认为您应该检查日志消息的原因。或者,您可以在调试模式下运行它,并在活动的onDestroy中设置一个中断,然后查看它是否正在运行调用。我检查了,当我离开活动时,该活动没有被销毁。当我返回时,它会在onCreate()中创建一个新的处理程序。您的新活动未连接到旧的处理程序。因此,您的新活动将不会从旧任务中获取消息。将继续考虑如何解决此问题,但我希望有人会插话。可能会查看广播接收器,但您的新活动可能已创建,然后必须等待一段时间,广播方才能发送message。我以前使用广播接收器,但它们速度太慢。我了解到处理程序连接到线程。我想知道是否有方法恢复旧的处理程序并在新活动中使用它。将第二个同步工作语句从for循环更改为if语句,以便在创建新活动时线程不会一直等到无穷大。如果(null!=WorkFragment.this){if(mReady){((WorkProgressListener).getActivity()).sendProgress(..):}}}oops-rewrite“因此,如果没有创建新活动,线程不会一直等到无穷大”