前段时间做了关于一个教材下载的机能,遇到了一个问题记录一下。
前提:
有两个dialog,开始下载画面startDialog(Dialog类型),下载中画面downloadingDialog(Dialog类型),都是在一个StudyDownloadDialog(DialogFragment类型)中管理的,当每次show()表示dialog的时候都会走StudyDownloadDialog的onCreate方法,这里面有3个关键部分:
1.onCreate的一个参数dialog赋值给全局变量mDialog。
protected Dialog onCreateDialogSub(Bundle savedInstanceState, Dialog dialog) {
mDialog = dialog;
2.new了一个Logic把当前对象传了过去
logic = new StudyDownloadLogic(mDialog, this);
3.根据不同的画面设置不同的布局view
switch (mDialogType) {
case DIALOG_TYPE_START_DOWNLOAD:
dialogStartDownload(dialog);
break;
case DIALOG_TYPE_DOWNLOADING:
dialogDownloading(dialog);
break;
再现流程:
当我点击开始画面时的下载按钮时,在onClick方法中调用了StudyDownloadLogic中的startContentsDownload()进行下载逻辑,同时dismiss关掉当前表示的画面,并展示下载中画面(再次走了StudyDownloadDialog的onCreate),之后logic想要更新下载中画面的进度条时,用户new StudyDownloadLogic时候第二个参数调用StudyDownloadDialog中的upDateProgressBar()更新进度条
//更新进度条
public void upDateProgressBar(int values) {
final ProgressBar progress = (ProgressBar) mDialog.findViewById(R.id.downloading_progress);
if (progress != null) {
Logger.d(getActivity(), "values:" + values);
progress.setProgress(values);
}
}
这个时候问题发生了,progress一直是null,无法更新进度条。经过调查发现当StudyDownloadLogic调用upDateProgressBar时,给当前这次的logic赋值的时机是下载开始画面的onCreate中,而这时候传过去的this也是开始画面的对象,所以mDialog.findViewById(R.id.downloading_progress);这里的mDIalog持有的数据还是上次开始下载画面的对象保存的,我想用开始画面的view中去找下载中画面的id肯定是无法找到的。
解决方法:
1.把onClick中调用开始下载的startContentsDownload()移动到onCreate中,并且判断类型下载中画面的时候在调用。
这个时候logic = new StudyDownloadLogic(mDialog, this); 的this就是当前下载中画面的对象了。
当用logic中传过来的this调回到StudyDownloadDialog中的upDateProgressBar时候mDialog因为是下载中画面保持的数据,所以mDialog.findViewById(R.id.downloading_progress);可以找到进度条,之后正常更新进度条。
if (mDialogType == DIALOG_TYPE_DOWNLOADING) {
startContentsDownload();
}
2.把StudyDownloadDialog的mDialog设置成static类型。
这个时候因为是静态的,生命周期存随着当前类走了,不管我用下载中还是下载开始时的传过去的this对象去更新进度条,只要mDialog被赋值成新的了,mDialog.findViewById(R.id.downloading_progress);就没有问题。