每次我编辑 PDFRendererBasicFragment java 代码
时mFileDescriptor = context.getAssets().openFd("sample.pdf").getParcelFileDescriptor();
到放置在资产文件夹中的其他 PDF,应用程序崩溃。
日志猫报告:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.pdfrendererbasic/com.example.android.pdfrendererbasic.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.pdf.PdfRenderer.getPageCount()' on a null object reference
为什么会这样?我什至尝试将我的 PDF 重命名为示例.pdf在构建之前,它仍然崩溃。原始代码一切正常,只是不让我替换 PDF。
堆栈跟踪:
02-11 11:11:50.130 18201-18201/com.example.android.pdfrendererbasic I/art: Not late-enabling -Xcheck:jni (already on)
02-11 11:11:50.130 18201-18201/com.example.android.pdfrendererbasic I/art: Late-enabling JIT
02-11 11:11:50.132 18201-18201/com.example.android.pdfrendererbasic I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000
02-11 11:11:50.201 18201-18201/com.example.android.pdfrendererbasic W/System: ClassLoader referenced unknown path: /data/app/com.example.android.pdfrendererbasic-1/lib/x86
02-11 11:11:50.252 18201-18201/com.example.android.pdfrendererbasic W/System.err: java.io.IOException: cannot create document. Error: 3
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.graphics.pdf.PdfRenderer.nativeCreate(Native Method)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.graphics.pdf.PdfRenderer.<init>(PdfRenderer.java:153)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at com.example.android.pdfrendererbasic.PdfRendererBasicFragment.openRenderer(PdfRendererBasicFragment.java:141)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at com.example.android.pdfrendererbasic.PdfRendererBasicFragment.onAttach(PdfRendererBasicFragment.java:108)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.Fragment.onAttach(Fragment.java:1380)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:932)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.BackStackRecord.run(BackStackRecord.java:793)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.FragmentController.execPendingActions(FragmentController.java:325)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.Activity.performStart(Activity.java:6252)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.ActivityThread.-wrap11(ActivityThread.java)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.os.Looper.loop(Looper.java:148)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at java.lang.reflect.Method.invoke(Native Method)
02-11 11:11:50.253 18201-18201/com.example.android.pdfrendererbasic W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
02-11 11:11:50.254 18201-18201/com.example.android.pdfrendererbasic W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-11 11:11:51.082 18201-18201/com.example.android.pdfrendererbasic D/AndroidRuntime: Shutting down VM
02-11 11:11:51.082 18201-18201/com.example.android.pdfrendererbasic E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.pdfrendererbasic, PID: 18201
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.pdfrendererbasic/com.example.android.pdfrendererbasic.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.pdf.PdfRenderer.getPageCount()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.pdf.PdfRenderer.getPageCount()' on a null object reference
at com.example.android.pdfrendererbasic.PdfRendererBasicFragment.showPage(PdfRendererBasicFragment.java:163)
at com.example.android.pdfrendererbasic.PdfRendererBasicFragment.onViewCreated(PdfRendererBasicFragment.java:101)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:988)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.BackStackRecord.run(BackStackRecord.java:793)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentController.execPendingActions(FragmentController.java:325)
at android.app.Activity.performStart(Activity.java:6252)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
PDFRendererBasicFragment.java:
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.pdfrendererbasic;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.pdf.PdfRenderer;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.IOException;
/**
* This fragment has a big {@ImageView} that shows PDF pages, and 2 {@link android.widget.Button}s to move between
* pages. We use a {@link android.graphics.pdf.PdfRenderer} to render PDF pages as {@link android.graphics.Bitmap}s.
*/
public class PdfRendererBasicFragment extends Fragment implements View.OnClickListener {
/**
* Key string for saving the state of current page index.
*/
private static final String STATE_CURRENT_PAGE_INDEX = "current_page_index";
/**
* File descriptor of the PDF.
*/
private ParcelFileDescriptor mFileDescriptor;
/**
* {@link android.graphics.pdf.PdfRenderer} to render the PDF.
*/
private PdfRenderer mPdfRenderer;
/**
* Page that is currently shown on the screen.
*/
private PdfRenderer.Page mCurrentPage;
/**
* {@link android.widget.ImageView} that shows a PDF page as a {@link android.graphics.Bitmap}
*/
private ImageView mImageView;
/**
* {@link android.widget.Button} to move to the previous page.
*/
private Button mButtonPrevious;
/**
* {@link android.widget.Button} to move to the next page.
*/
private Button mButtonNext;
public PdfRendererBasicFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_pdf_renderer_basic, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Retain view references.
mImageView = (ImageView) view.findViewById(R.id.image);
mButtonPrevious = (Button) view.findViewById(R.id.previous);
mButtonNext = (Button) view.findViewById(R.id.next);
// Bind events.
mButtonPrevious.setOnClickListener(this);
mButtonNext.setOnClickListener(this);
// Show the first page by default.
int index = 0;
// If there is a savedInstanceState (screen orientations, etc.), we restore the page index.
if (null != savedInstanceState) {
index = savedInstanceState.getInt(STATE_CURRENT_PAGE_INDEX, 0);
}
showPage(index);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
openRenderer(activity);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(activity, "Error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
activity.finish();
}
}
@Override
public void onDetach() {
try {
closeRenderer();
} catch (IOException e) {
e.printStackTrace();
}
super.onDetach();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mCurrentPage) {
outState.putInt(STATE_CURRENT_PAGE_INDEX, mCurrentPage.getIndex());
}
}
/**
* Sets up a {@link android.graphics.pdf.PdfRenderer} and related resources.
*/
private void openRenderer(Context context) throws IOException {
// In this sample, we read a PDF from the assets directory.
mFileDescriptor = context.getAssets().openFd("sample.pdf").getParcelFileDescriptor();
// This is the PdfRenderer we use to render the PDF.
mPdfRenderer = new PdfRenderer(mFileDescriptor);
}
/**
* Closes the {@link android.graphics.pdf.PdfRenderer} and related resources.
*
* @throws java.io.IOException When the PDF file cannot be closed.
*/
private void closeRenderer() throws IOException {
if (null != mCurrentPage) {
mCurrentPage.close();
}
mPdfRenderer.close();
mFileDescriptor.close();
}
/**
* Shows the specified page of PDF to the screen.
*
* @param index The page index.
*/
private void showPage(int index) {
if (mPdfRenderer.getPageCount() <= index) {
return;
}
// Make sure to close the current page before opening another one.
if (null != mCurrentPage) {
mCurrentPage.close();
}
// Use `openPage` to open a specific page in PDF.
mCurrentPage = mPdfRenderer.openPage(index);
// Important: the destination bitmap must be ARGB (not RGB).
Bitmap bitmap = Bitmap.createBitmap(mCurrentPage.getWidth(), mCurrentPage.getHeight(),
Bitmap.Config.ARGB_8888);
// Here, we render the page onto the Bitmap.
// To render a portion of the page, use the second and third parameter. Pass nulls to get
// the default result.
// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
// We are ready to show the Bitmap to user.
mImageView.setImageBitmap(bitmap);
updateUi();
}
/**
* Updates the state of 2 control buttons in response to the current page index.
*/
private void updateUi() {
int index = mCurrentPage.getIndex();
int pageCount = mPdfRenderer.getPageCount();
mButtonPrevious.setEnabled(0 != index);
mButtonNext.setEnabled(index + 1 < pageCount);
getActivity().setTitle(getString(R.string.app_name_with_index, index + 1, pageCount));
}
/**
* Gets the number of pages in the PDF. This method is marked as public for testing.
*
* @return The number of pages.
*/
public int getPageCount() {
return mPdfRenderer.getPageCount();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.previous: {
// Move to the previous page
showPage(mCurrentPage.getIndex() - 1);
break;
}
case R.id.next: {
// Move to the next page
showPage(mCurrentPage.getIndex() + 1);
break;
}
}
}
}
将 gradle 版本从 2.2.0 降级到 2.1.2 并且崩溃将消失。
在build.gradle(Project(中替换
classpath 'com.android.tools.build:gradle:2.2.0'
跟
classpath 'com.android.tools.build:gradle:2.1.2'
此处报告和描述了您提到的相同问题。问题似乎出在Android Studio创建最终apk文件的方式上。虽然给定的链接中提供了手动重新打包apk文件的解决方案,但这不是很实用。该错误似乎没有任何其他简单的解决方案。
编辑
这是提供的链接中的解决方案。但是,报告的问题提到的错误消息略有不同,因此这可能不起作用。
- 启动安卓工作室
- 点击导入安卓代码示例
- 选择图形> PDF 渲染器基本
- 单击下一步
- 单击完成。
- 单击运行>运行"应用程序">
运行应用程序会隐式创建 Application/build/outputs/apk/Application-debug.apk 文件。
6.a:健全性检查:验证 META-INF 条目是否位于文件末尾:
$ unzip -lv Application/build/outputs/apk/Application-debug.apk
...
1569 Defl:N 702 55% 12-16-14 17:35 c7cb7a03 META-INF/MANIFEST.MF
1598 Defl:N 724 55% 12-16-14 17:35 034c0dfc META-INF/CERT.SF
776 Defl:N 605 22% 12-16-14 17:35 2be8b27c META-INF/CERT.RSA
-------- ------- --- -------
1565085 849785 46% 21 files
使用 jarsigner 手动对包重新签名。这样做的目的是确保 META-INF 条目位于.apk的开头:
$ 是的安卓 | keytool -genkey -v -keystore demo.keystore -alias demo -keyalg RSA -keysize 2048 -有效期 10000 -dname "CN=Mark Smith"$ cp 应用程序/构建/输出/apk/应用程序调试.apk A.apk$ zip -d A.apk META-INF/MANIFEST.中频$ zip -d A.apk META-INF/CERT.顺丰$ zip -d A.apk META-INF/CERT.RSA$ jarsigner -keystore demo.keystore -storepass android \ -keypass android -digestalg SHA1 -sigalg md5withRSA \ -signedjar A-unaligned.apk A.apk \ 演示$ 拉链对齐 4 A 未对齐.apk A 对齐.apk
安装重新签名的软件包:
$ adb uninstall com.example.android.pdfrendererbasic$ 亚行安装 A 对齐.apk
运行新包:
$ adb shell am start com.example.android.pdfrendererbasic/.主活动