Android runOnUiThread 在按下后退按钮时崩溃
Android runOnUiThread crash when pressing Back button
我正在使用 DownloadManager 从服务器下载文件,我正在从适配器下载文件,我正在使用 runOnUiThread 在片段中显示下载进度。
它运行良好,但是当我在下载时按下后退按钮时,runOnUiThread 抛出 NullPointerException。
我尝试使用 if 语句在 onPause 中放置一个变量来停止该方法,但它也不起作用。
您建议如何解决此崩溃问题?
这是我的代码:
new Thread(new Runnable() {
@Override
public void run() {
downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(myDownloadReference);
Cursor cursor = downloadManager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
downloadingDocs.remove(doc);
//remove the progressBar when download is complete
fragment.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
finalHolder2.downloadProgress.setVisibility(View.INVISIBLE);
}
});
//check if it's the last download and open it.
if (downloadingDocs.size() == 0) {
actionIntentOpenDocs(doc, saveFile);
}
}
//final double dl_progress = (bytes_downloaded / bytes_total) * 100;
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
//display the download progress
fragment.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if(Constants.stopUiThreadWork == null) {
finalHolder2.downloadProgress.setProgress((int) dl_progress);
}
}
});
cursor.close();
}
}
}).start();
这条线崩溃了:
fragment.getActivity().runOnUiThread(new Runnable() {
崩溃堆栈跟踪:
FATAL EXCEPTION: Thread-4807
Process: com.appus.app, PID: 6553
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.runOnUiThread(java.lang.Runnable)' on a null object reference
at com.availo.app.UI.adapters.MainFragmentDocumentAdapter.run(MainFragmentDocumentAdapter.java:265)
at java.lang.Thread.run(Thread.java:818)
管理此类事情的最佳方法是通过 Service. The reason is that a service can better manage background threads, even if the activity isn't running, while things like an AsyncTask will stop working when the activity is done. Take a look at this site 如何设置下载服务。
在执行 runOnUiThread 之前尝试检查您的 activity:
/** check if activity still exist */
if (getActivity() == null) {
return;
}
getActivity().runOnUiThread(new Runnable() {
...
});
"you shouldn't have returns littered through your code? (...)"
"cleaner" 是它变得模棱两可的地方。我们不是在编写汇编程序,所以我看不出这与这里有什么关系。苹果和橙子。在编写方法时,尽可能使用单个 return 可以提高可读性和维护性。如果您的代码变得复杂或需要遵循此编码风格的多个 return 语句,则该方法可能需要进一步分析和分解。 – 朱利奥
@giulio - 参考资料、出版物、规格 - 我在你的评论中没有看到任何东西 - 但我可以给你一些阅读和获得一些知识。
你可以从这里开始吹嘘:
然后读我最喜欢的:
http://www.yegor256.com/2015/08/18/multiple-return-statements-in-oop.html
在我的例子中,我在片段中使用 requireActivity().runOnUiThread
,我只是将其更改为 activity?.runOnUiThread
,这解决了我的问题!
我正在使用 DownloadManager 从服务器下载文件,我正在从适配器下载文件,我正在使用 runOnUiThread 在片段中显示下载进度。 它运行良好,但是当我在下载时按下后退按钮时,runOnUiThread 抛出 NullPointerException。 我尝试使用 if 语句在 onPause 中放置一个变量来停止该方法,但它也不起作用。
您建议如何解决此崩溃问题?
这是我的代码:
new Thread(new Runnable() {
@Override
public void run() {
downloading = true;
while (downloading) {
DownloadManager.Query q = new DownloadManager.Query();
q.setFilterById(myDownloadReference);
Cursor cursor = downloadManager.query(q);
cursor.moveToFirst();
int bytes_downloaded = cursor.getInt(cursor
.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {
downloading = false;
downloadingDocs.remove(doc);
//remove the progressBar when download is complete
fragment.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
finalHolder2.downloadProgress.setVisibility(View.INVISIBLE);
}
});
//check if it's the last download and open it.
if (downloadingDocs.size() == 0) {
actionIntentOpenDocs(doc, saveFile);
}
}
//final double dl_progress = (bytes_downloaded / bytes_total) * 100;
final int dl_progress = (int) ((bytes_downloaded * 100l) / bytes_total);
//display the download progress
fragment.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if(Constants.stopUiThreadWork == null) {
finalHolder2.downloadProgress.setProgress((int) dl_progress);
}
}
});
cursor.close();
}
}
}).start();
这条线崩溃了:
fragment.getActivity().runOnUiThread(new Runnable() {
崩溃堆栈跟踪:
FATAL EXCEPTION: Thread-4807
Process: com.appus.app, PID: 6553
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.runOnUiThread(java.lang.Runnable)' on a null object reference
at com.availo.app.UI.adapters.MainFragmentDocumentAdapter.run(MainFragmentDocumentAdapter.java:265)
at java.lang.Thread.run(Thread.java:818)
管理此类事情的最佳方法是通过 Service. The reason is that a service can better manage background threads, even if the activity isn't running, while things like an AsyncTask will stop working when the activity is done. Take a look at this site 如何设置下载服务。
在执行 runOnUiThread 之前尝试检查您的 activity:
/** check if activity still exist */
if (getActivity() == null) {
return;
}
getActivity().runOnUiThread(new Runnable() {
...
});
"you shouldn't have returns littered through your code? (...)"
"cleaner" 是它变得模棱两可的地方。我们不是在编写汇编程序,所以我看不出这与这里有什么关系。苹果和橙子。在编写方法时,尽可能使用单个 return 可以提高可读性和维护性。如果您的代码变得复杂或需要遵循此编码风格的多个 return 语句,则该方法可能需要进一步分析和分解。 – 朱利奥
@giulio - 参考资料、出版物、规格 - 我在你的评论中没有看到任何东西 - 但我可以给你一些阅读和获得一些知识。
你可以从这里开始吹嘘:
然后读我最喜欢的:
http://www.yegor256.com/2015/08/18/multiple-return-statements-in-oop.html
在我的例子中,我在片段中使用 requireActivity().runOnUiThread
,我只是将其更改为 activity?.runOnUiThread
,这解决了我的问题!