Android之预览PDF文件

Android之预览PDF文件

     上周临时收到客户的说明书,说要放在应用里显示,本来觉得一个非常简单的事情没想到一波三折。

      第一波:我使用了pdfViewer控件:(相了解的可以查看:https://github.com/barteksc/AndroidPdfViewer

      遇到的坑就是 因为设备是横屏的,这个控件在手机上预览pdf很不错,我一下子没有找到横向铺满的方法,因此显示起来页面显的非常小,由于时间比较急没有去细细研究所以弃用了。

      第二波:到这个时候我就立马换了一个思路。改用WebView,过程稍微复杂点 但是效果还是不错的 满足了需求。

      首先,下载PDF.js放到assets目录下。如下:  

         

 

         然后就是使用:布局文件就不贴出来了。

	private void loadWebPdf() {
		webView = (WebView) findViewById(R.id.pdf_webView);
		WebSettings webSettings = webView.getSettings();
		webSettings.setJavaScriptEnabled(true);
		webSettings.setAllowFileAccess(true);
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
			webSettings.setAllowUniversalAccessFromFileURLs(true);
			webSettings.setAllowUniversalAccessFromFileURLs(true);
		}
		webView.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=" + "file:///android_asset/vehicle-help-chinese.pdf");
	}

感觉一切都是相当的完美。如果是一般应用到这里也就没什么问题了。

第三波: 运行的时候发现系统一直报 Error inflating class android.webkit.WebView.这就很尴尬了,然后查了下,试了几个方法都没有用,后面仔细看还有For security reasons, WebView is not allowed in privileged processesFor security reasons, WebView is not allowed in privileged processes(出于安全原因,特权进程中不允许使用WebView。出于安全原因,特权进程中不允许使用WebView)。这就很尴尬了,忘了说了应用是系统及应用系统版本7.1.2。(Android开发系统应用(android.uid.system)使用webview报错)。

 

查了下 谷歌不知道从啥时候开始全面禁止系统应用使用webview。查看源码获悉在WebviewFactory代码中某个静态实例初始化之前判断api版本并抛出错误。知道是这个原因后,心里有底了,方法总比困难多嘛,既然准备用WebView来预览pdf了就不要轻易放弃。方向如下:

在使用webview之前,使用hook(钩子)方法,给该变量赋值。哈哈 这样就可以避免这个问题了;代码如下:

	/**
	 * 使用WebView避免系统检查抛出异常
	 */
	public static void checkWebView() {
		LogUtils.d(TAG, "checkWebView()");
		int sdkInt = Build.VERSION.SDK_INT;
		try {
			//拿到 WebViewFactory 类
			Class<?> factoryClass = Class.forName("android.webkit.WebViewFactory");
			//拿到类对应的 field
			Field field = factoryClass.getDeclaredField("sProviderInstance");
			//field为private,设置为可访问的
			field.setAccessible(true);
			//拿到 WebViewFactory 的 sProviderInstance 实例
			//sProviderInstance 是 static 类型,不需要传入具体对象
			Object sProviderInstance = field.get(null);
			if (sProviderInstance != null) {
				return;
			}
			Method getProviderClassMethod;
			if (sdkInt > 22) {
				getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass");
			} else if (sdkInt == 22) {
				getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass");
			} else {
				return;
			}
			getProviderClassMethod.setAccessible(true);
			Class<?> providerClass = (Class<?>) getProviderClassMethod.invoke(factoryClass);
			Class<?> delegateClass = Class.forName("android.webkit.WebViewDelegate");
			Constructor<?> providerConstructor = providerClass.getConstructor(delegateClass);
			if (providerConstructor != null) {
				LogUtils.d(TAG, "providerConstructor != null");
				providerConstructor.setAccessible(true);
				Constructor<?> declaredConstructor = delegateClass.getDeclaredConstructor();
				declaredConstructor.setAccessible(true);
				//利用反射创建了 sProviderInstance
				sProviderInstance = providerConstructor.newInstance(declaredConstructor.newInstance());
				//完成 sProviderInstance 赋值
				field.set("sProviderInstance", sProviderInstance);
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

搞定收工,预览了下效果还是蛮不错的。只是加载稍微有点点慢。

最近在优化内存发现这个由于用的WebView内存占用比较大,而且退出后内存降不下去。导致整个应用内存占用比较大。测试了很大方法都不能从根本上解决,最后只好把界面设置成一个单独的进程。界面退出的时候直接System.exit(0);

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是两种在Android预览PDF文件的方法: 1. 使用Android PdfViewerAndroid PdfViewer是一个开源库,可以在Android应用中实现PDF文件预览。你可以通过在项目的build.gradle文件中添加依赖来使用该库: ```groovy implementation 'com.github.barteksc:android-pdf-viewer:2.8.2' ``` 然后,在你的Activity中,你可以使用PdfView来加载和显示PDF文件: ```java import com.github.barteksc.pdfviewer.PDFView; public class MainActivity extends AppCompatActivity { private PDFView pdfView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pdfView = findViewById(R.id.pdfView); pdfView.fromAsset("sample.pdf") // 从assets文件夹加载PDF文件 .load(); } } ``` 在上面的代码中,我们假设你的项目中有一个名为"sample.pdf"的PDF文件放在assets文件夹中。你可以根据实际情况修改文件名和路径。 2. 使用Mozilla的PDF.jsPDF.js是一个由Mozilla开发的JavaScript库,可以在Web浏览器中预览PDF文件。你可以将PDF.js集成到你的Android应用中,通过WebView加载并显示PDF文件。首先,你需要将PDF.js文件添加到你的项目中。你可以从GitHub上下载PDF.js文件,并将其放置在你的项目的assets文件夹中。然后,在你的Activity中,你可以使用WebView来加载PDF.js文件PDF文件: ```java import android.os.Bundle; import android.webkit.WebSettings; import android.webkit.WebView; public class MainActivity extends AppCompatActivity { private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = findViewById(R.id.webView); WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); webView.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=sample.pdf"); } } ``` 在上面的代码中,我们假设你将PDF.js文件放在了assets文件夹的"pdfjs"子文件夹中,并且你的项目中有一个名为"sample.pdf"的PDF文件。你可以根据实际情况修改文件名和路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值