窗口泄漏错误
遇到问题
我在创建进度对话框时
dialog = new ProgressDialog(InstallerActivity.this);
我的资产文件夹中有 12 个 apk 文件。我正在尝试使用此功能将所有 12 个资源复制到 SD 卡,
private void CopyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
String[] files2 = null;
try {
files2 = assetManager.list("");
List<String> sb = new ArrayList();
for (String curfile : files2) {
if (curfile.endsWith("apk")) {
sb.add(curfile);
}
}
files = sb.toArray(new String[sb.size()]);
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
dialog.setMax(files.length);
dialog.setProgress(0);
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
out = new FileOutputStream(externalPath + "/" + appsdir + "/" + filename);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
dialog.incrementProgressBy(1);
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
但我的应用程序总是在 10 个文件上崩溃,并出现错误:窗口泄漏。如果我删除 Log.e,它不会崩溃,但仍然只复制 10 个文件,而不是 12 个!
谷歌搜索后,我发现我需要使用 dialog.dismiss()
,但我现在不想关闭它,它需要显示另外 2 个元素的进度!
Logcat:
11-19 18:22:13.473: D/dalvikvm(19931): GC_EXTERNAL_ALLOC freed 872 objects / 58552 bytes in 88ms
11-19 18:22:57.903: D/asset(19931): Data exceeds UNCOMPRESS_DATA_MAX (4412833 vs 3145728)
11-19 18:22:57.913: W/dalvikvm(19931): threadid=9: thread exiting with uncaught exception (group=0x4001d930)
11-19 18:22:57.943: E/AndroidRuntime(19931): FATAL EXCEPTION: Thread-10
11-19 18:22:57.943: E/AndroidRuntime(19931): java.lang.NullPointerException: println needs a message
11-19 18:22:57.943: E/AndroidRuntime(19931): at android.util.Log.println_native(Native Method)
11-19 18:22:57.943: E/AndroidRuntime(19931): at android.util.Log.e(Log.java:215)
11-19 18:22:57.943: E/AndroidRuntime(19931): at com.installer.InstallerActivity.CopyAssets(InstallerActivity.java:284)
11-19 18:22:57.943: E/AndroidRuntime(19931): at com.installer.InstallerActivity.access$1(InstallerActivity.java:246)
11-19 18:22:57.943: E/AndroidRuntime(19931): at com.installer.InstallerActivity$3$2.run(InstallerActivity.java:169)
11-19 18:22:57.943: E/AndroidRuntime(19931): at java.lang.Thread.run(Thread.java:1096)
11-19 18:22:58.883: E/WindowManager(19931): Activity com.installer.InstallerActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@460905c0 that was originally added here
11-19 18:22:58.883: E/WindowManager(19931): android.view.WindowLeaked: Activity com.installer.InstallerActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@460905c0 that was originally added here
11-19 18:22:58.883: E/WindowManager(19931): at android.view.ViewRoot.<init>(ViewRoot.java:247)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.Window$LocalWindowManager.addView(Window.java:424)
11-19 18:22:58.883: E/WindowManager(19931): at android.app.Dialog.show(Dialog.java:241)
11-19 18:22:58.883: E/WindowManager(19931): at com.installer.InstallerActivity$3.onClick(InstallerActivity.java:123)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.View.performClick(View.java:2449)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.View$PerformClick.run(View.java:9027)
11-19 18:22:58.883: E/WindowManager(19931): at android.os.Handler.handleCallback(Handler.java:587)
11-19 18:22:58.883: E/WindowManager(19931): at android.os.Handler.dispatchMessage(Handler.java:92)
11-19 18:22:58.883: E/WindowManager(19931): at android.os.Looper.loop(Looper.java:123)
11-19 18:22:58.883: E/WindowManager(19931): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-19 18:22:58.883: E/WindowManager(19931): at java.lang.reflect.Method.invokeNative(Native Method)
11-19 18:22:58.883: E/WindowManager(19931): at java.lang.reflect.Method.invoke(Method.java:521)
11-19 18:22:58.883: E/WindowManager(19931): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-19 18:22:58.883: E/WindowManager(19931): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-19 18:22:58.883: E/WindowManager(19931): at dalvik.system.NativeStart.main(Native Method)
编辑: 看来这不是进度对话框问题。修复了 log.e 行并出现新错误:
11-19 19:17:39.533: E/tag(20559): Something went wrong while copying files
11-19 19:17:39.533: E/tag(20559): java.io.IOException
11-19 19:17:39.533: E/tag(20559): at android.content.res.AssetManager.readAsset(Native Method)
11-19 19:17:39.533: E/tag(20559): at android.content.res.AssetManager.access$700(AssetManager.java:36)
11-19 19:17:39.533: E/tag(20559): at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:571)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity.copyFile(InstallerActivity.java:292)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity.CopyAssets(InstallerActivity.java:276)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity.access$1(InstallerActivity.java:247)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity$3$2.run(InstallerActivity.java:170)
11-19 19:17:39.533: E/tag(20559): at java.lang.Thread.run(Thread.java:1096)
为什么无法从资产中复制第 10 个元素之后?
谢谢
I have a problem
I created my progress dialog
dialog = new ProgressDialog(InstallerActivity.this);
I have 12 apk files in my assets folder. I am trying to copy all 12 assets to sdcard with this function
private void CopyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
String[] files2 = null;
try {
files2 = assetManager.list("");
List<String> sb = new ArrayList();
for (String curfile : files2) {
if (curfile.endsWith("apk")) {
sb.add(curfile);
}
}
files = sb.toArray(new String[sb.size()]);
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
dialog.setMax(files.length);
dialog.setProgress(0);
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
out = new FileOutputStream(externalPath + "/" + appsdir + "/" + filename);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
dialog.incrementProgressBy(1);
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
But my app always crashes on 10 files, with an error: Window leaked. If I delete Log.e, it wont crash, but still copy only 10 files, not 12!
After googling I found that I need to use dialog.dismiss()
, but I dont want to dissmiss it now, it is needed to show progress of 2 more elements!
Logcat:
11-19 18:22:13.473: D/dalvikvm(19931): GC_EXTERNAL_ALLOC freed 872 objects / 58552 bytes in 88ms
11-19 18:22:57.903: D/asset(19931): Data exceeds UNCOMPRESS_DATA_MAX (4412833 vs 3145728)
11-19 18:22:57.913: W/dalvikvm(19931): threadid=9: thread exiting with uncaught exception (group=0x4001d930)
11-19 18:22:57.943: E/AndroidRuntime(19931): FATAL EXCEPTION: Thread-10
11-19 18:22:57.943: E/AndroidRuntime(19931): java.lang.NullPointerException: println needs a message
11-19 18:22:57.943: E/AndroidRuntime(19931): at android.util.Log.println_native(Native Method)
11-19 18:22:57.943: E/AndroidRuntime(19931): at android.util.Log.e(Log.java:215)
11-19 18:22:57.943: E/AndroidRuntime(19931): at com.installer.InstallerActivity.CopyAssets(InstallerActivity.java:284)
11-19 18:22:57.943: E/AndroidRuntime(19931): at com.installer.InstallerActivity.access$1(InstallerActivity.java:246)
11-19 18:22:57.943: E/AndroidRuntime(19931): at com.installer.InstallerActivity$3$2.run(InstallerActivity.java:169)
11-19 18:22:57.943: E/AndroidRuntime(19931): at java.lang.Thread.run(Thread.java:1096)
11-19 18:22:58.883: E/WindowManager(19931): Activity com.installer.InstallerActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@460905c0 that was originally added here
11-19 18:22:58.883: E/WindowManager(19931): android.view.WindowLeaked: Activity com.installer.InstallerActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@460905c0 that was originally added here
11-19 18:22:58.883: E/WindowManager(19931): at android.view.ViewRoot.<init>(ViewRoot.java:247)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.Window$LocalWindowManager.addView(Window.java:424)
11-19 18:22:58.883: E/WindowManager(19931): at android.app.Dialog.show(Dialog.java:241)
11-19 18:22:58.883: E/WindowManager(19931): at com.installer.InstallerActivity$3.onClick(InstallerActivity.java:123)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.View.performClick(View.java:2449)
11-19 18:22:58.883: E/WindowManager(19931): at android.view.View$PerformClick.run(View.java:9027)
11-19 18:22:58.883: E/WindowManager(19931): at android.os.Handler.handleCallback(Handler.java:587)
11-19 18:22:58.883: E/WindowManager(19931): at android.os.Handler.dispatchMessage(Handler.java:92)
11-19 18:22:58.883: E/WindowManager(19931): at android.os.Looper.loop(Looper.java:123)
11-19 18:22:58.883: E/WindowManager(19931): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-19 18:22:58.883: E/WindowManager(19931): at java.lang.reflect.Method.invokeNative(Native Method)
11-19 18:22:58.883: E/WindowManager(19931): at java.lang.reflect.Method.invoke(Method.java:521)
11-19 18:22:58.883: E/WindowManager(19931): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-19 18:22:58.883: E/WindowManager(19931): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-19 18:22:58.883: E/WindowManager(19931): at dalvik.system.NativeStart.main(Native Method)
Edit:
Seems like this is not a progressdialog issue. Fixed log.e line and got new error:
11-19 19:17:39.533: E/tag(20559): Something went wrong while copying files
11-19 19:17:39.533: E/tag(20559): java.io.IOException
11-19 19:17:39.533: E/tag(20559): at android.content.res.AssetManager.readAsset(Native Method)
11-19 19:17:39.533: E/tag(20559): at android.content.res.AssetManager.access$700(AssetManager.java:36)
11-19 19:17:39.533: E/tag(20559): at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:571)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity.copyFile(InstallerActivity.java:292)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity.CopyAssets(InstallerActivity.java:276)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity.access$1(InstallerActivity.java:247)
11-19 19:17:39.533: E/tag(20559): at com.installer.InstallerActivity$3$2.run(InstallerActivity.java:170)
11-19 19:17:39.533: E/tag(20559): at java.lang.Thread.run(Thread.java:1096)
Why it cant copy after 10th element from assets?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
日志中的堆栈跟踪表明您正在尝试记录一条空消息。由于您正在执行的唯一日志记录是
Log.e("tag", e.getMessage())
,这意味着您的异常之一没有消息。尝试使用
Log.e("tag", "复制文件时出现问题", e)
代替。这将打印问题的真实堆栈跟踪。有关泄漏窗口的消息只是应用程序崩溃的症状,因此无法正确地自行清理。 (在这种情况下,将涉及关闭对话框。)
根据下面的讨论,真正的问题是其中一个资源文件太大。当资源文件放入APK文件中时,大多数资源文件都会被压缩。不幸的是,Android 只能解压小于特定大小的文件。 (确切的大小因版本和平台而异。)
诀窍是避免压缩文件。如果您要手动使用命令行工具,aapt 工具有一个选项可以执行此操作。如果您使用 eclipse,最简单的方法是将 apk 文件重命名为看起来像图像文件,因为它们没有被压缩。
尝试将资源文件夹中的 apk 文件重命名为 .png,然后在复制时重命名。
The stack trace in the log says that you are trying to log a message that is null. Since the only logging you are doing is
Log.e("tag", e.getMessage())
, this means that one of your exceptions doesn't have a message.Try using
Log.e("tag", "Something went wrong while copying files", e)
instead. This will print the real stack trace of your problem.The message about leaking a window is just a symptom of your application crashing and thus not cleaning up after itself properly. (Which in this case would involve dismissing the dialog.)
According to the discussion below, the real problem is that one of the asset files is too big. When asset files are put in the APK file, most of them are compressed. Unfortunately, Android can only unpack files below a certain size. (The exact size varies between versions and platforms.)
The trick is to avoid getting the file compressed. If you were to use the command line tools manually, there is an option to the aapt tool to do this. If you are using eclipse, the easiest way is to rename the apk files look like an image file, since they aren't compressed.
Try renaming your apk files to .png in the asset folder and then rename them as you copy them.
请原谅我的误解。
问题出在资产上。我关注了这篇博文 http:// /ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/ 并将文件重命名为 .jpg。现在可以了。
似乎这是一个 android 错误,不允许处理大于 4mb 的资产文件。
谢谢大家的帮助!
Excuse me for that misunderstanding.
The problem was with assets. I folowed this blog post http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/ and renamed files to .jpg. now it works.
Seems that it is an android bug that does-not allow to handle assets-files bigger than 4mb.
Thanks everyone for you help!