好久没更新了,今天说说打包加固之后的apk有哪些坑, 在AS上直接运行的时候跑的很流畅,速度也很快,可以说已经过了测试的坎了,剩下的就打包加固,然后上线的问题了。但是....
先来看看下面的一段崩溃信息
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference (Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference)
AndroidRuntime: FATAL EXCEPTION: Thread-32
Process: PID: 27584
org.apache.commons.logging.LogConfigurationException: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference (Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:7)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:3)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:1)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:1)
at org.apache.http.impl.client.CloseableHttpClient.<init>(CloseableHttpClient.java:2)
at org.apache.http.impl.client.AbstractHttpClient.<init>(AbstractHttpClient.java:1)
at org.apache.http.impl.client.DefaultHttpClient.<init>(DefaultHttpClient.java:4)
at utils.r.a(HttpUtil.java:53)
at activity.login.RegistActivity$b.run(RegistActivity.java:8)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference
at org.apache.commons.logging.impl.LogFactoryImpl.createLogFromClass(LogFactoryImpl.java:27)
at org.apache.commons.logging.impl.LogFactoryImpl.discoverLogImplementation(LogFactoryImpl.java:19)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:2)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:3)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:1)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:1)
at org.apache.http.impl.client.CloseableHttpClient.<init>(CloseableHttpClient.java:2)
at org.apache.http.impl.client.AbstractHttpClient.<init>(AbstractHttpClient.java:1)
at org.apache.http.impl.client.DefaultHttpClient.<init>(DefaultHttpClient.java:4)
at utils.r.a(HttpUtil.java:53)
at activity.login.RegistActivity$b.run(RegistActivity.java:8)
at java.lang.Thread.run(Thread.java:764)
What ??? 这是什么???
这一看是空指针了, 据说空指针是最好找的问题,但是这根本没有具体的对象好吧。。。
因为是之前的项目,所以我不知道都有哪些地方有,只好全局搜索....
然后就开启了各种找bug的模式,首先在字符串上找String.trim(), (这个方法是去除前后空格返回一个字符串)把项目中的字符串调用这个方法的地方全部改掉, 直接打包加固之后测试...
继续崩溃...
FATAL EXCEPTION: main
Process: PID: 4728
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.dolphin.edu.adapter.x1.h.a(NewJcAdapter.java:12)
at com.dolphin.edu.adapter.x1.h.onBindViewHolder(NewJcAdapter.java:1)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:1)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:55)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:2)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:1)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:3)
....省略崩溃代码
Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
再然后就
ActivityManager: ANR in com.dolphin.edu
PID: 4728
Reason: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50200014 (has extras) }
Load: 23.78 / 22.88 / 22.63
CPU usage from 7197ms to 16124ms later (2020-03-17 13:52:17.206 to 2020-03-17 13:52:26.133) with 99% awake:
9.2% 20080/com.tencent.mobileqq: 6% user + 3.2% kernel / faults: 1210 minor 6 major
0% 852/media.codec: 0% user + 0% kernel / faults: 4753 minor 108 major
5.8% 1390/system_server: 2.1% user + 3.6% kernel / faults: 249 minor
2.7% 2021/com.android.phone: 1.5% user + 1.2% kernel / faults: 1825 minor 513 major
2.7% 27411/adbd: 0.4% user + 2.3% kernel / faults: 48059 minor
0% 839/media.extractor: 0% user + 0% kernel / faults: 3128 minor 94 major
2.4% 288/exe_cq: 0% user + 2.4% kernel
0.1% 3076/com.coloros.appmanager: 0% user + 0% kernel / faults: 2108 minor 384 major
0.8% 26909/com.oppo.gestureservice: 0.4% user + 0.3% kernel / faults: 1826 minor 394 major
....省略...
这又是什么??? 又是字符串空了, 然后ANR了, 这又是什么鬼...
没办法, 又开始找bug
发现跟recyclerView 还有适配器一点关系都没有, 找到这头都已经炸了, 为什么直接运行的时候没有问题, 只要一打包就会出现问题呢?
// httpPost.setHeader("Range", "bytes=" + "");
// httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
// HttpClient client = new DefaultHttpClient();
// // 请求超时
// client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 20000);
// // 读取超时
// client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 20000);
//
// // HttpClient 没有注册 https 协议 会报错
// client.getConnectionManager()
// .getSchemeRegistry()
// .register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
//
// httpResponse = client.execute(httpPost);
后来发现是这里的问题,貌似协议的问题,我也在好奇为什么之前一直没有问题呢,原来是后台把http换成https了, 但是这里也注册了啊, 为什么还会这样呢
虽然注册了, 但是默认请求执行的还是HTTP,此配置还是会出现问题或连接被中止,以至于出现http协议错误,但参数会报字符串空的错误(肯定是有参数传的null 或者没有赋值),(我是这么理解的, 不知道对不对, 如果不对 请告知...)
更换请求框架,把返回值返回,虽然解决了这个问题, 但是又有新的问题
打开扫一扫app崩溃了, 之前不是还好好的么,为什么还会出现问题啊,啊啊啊啊啊 已经能发现已经被这个项目折磨的受不了了
java.lang.RuntimeException: Unable to start activity ComponentInfo{activity.CaptureActivity}: org.apache.commons.logging.LogConfigurationException: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference (Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3187)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3324)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:113)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:71)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2050)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:226)
at android.app.ActivityThread.main(ActivityThread.java:7223)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:576)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:956)
Caused by: org.apache.commons.logging.LogConfigurationException: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference (Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference)
What ??? 这怎么又回来了?? 还是这个问题? 此时已经想把电脑砸了...
不过还好已经给了具体的类,不像之前就是闪退崩溃连个毛都没有,那这次就在这里面找吧,
从头找到尾,并没有发现字符串空指针的问题,这报的到底是不是空指针啊....
又翻了一遍,发现
bitmap = ImageManager.from(mContext).displayResoureImageBitmap(resources, R.drawable.scanning);
public Bitmap displayResoureImageBitmap(Resources resources, int resId) {
if (resId >= 0) {
if (mMemoryCache.get(ImageResourceId + resId) == null) {
try {
InputStream is = resources.openRawResource(resId);
// Bitmap bitmap = BitmapFactory.decodeStream(is, null,
// initBitmapOptions(resId));
Bitmap bitmap = BitmapFactory.decodeStream(is);
// Bitmap bitmap =
// BitmapFactory.decodeResource(imageView.getResources(),
// resId, initBitmapOptions(imageView, resId));
if (bitmap != null)
mMemoryCache.put(ImageResourceId + resId, bitmap);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
}
return mMemoryCache.get(ImageResourceId + resId);
}
return null;
}
是这行代码的锅,行吧,算你狠, 我不用总行了吧 于是换成了
bitmap = BitmapFactory.decodeResource(resources, R.drawable.scanning);
这它不香么...
写那么多咱也不知道到底写个啥...
发现这个类用到的地方还是挺多的, 就看了一眼,不看不知道, 一看吓一跳,
/**
* 显示系统资源图片使用
*
* @param imageView
* 加载图片的控�?
* @param resId
* 系统图片
*/
// for resoure id
public void displayResoureImage(ImageView imageView, int resId) {
if (imageView == null) {
return;
}
if (resId >= 0) {
Bitmap bitmap = mMemoryCache.get(ImageResourceId + resId);
if (bitmap == null || bitmap.isRecycled()) {
try {
InputStream is = imageView.getResources().openRawResource(resId);
bitmap = BitmapFactory.decodeStream(is);
// Bitmap bitmap =
// BitmapFactory.decodeResource(imageView.getResources(),
// resId, initBitmapOptions(imageView, resId));
if (bitmap != null)
mMemoryCache.put(ImageResourceId + resId, bitmap);
} catch (OutOfMemoryError e) {
e.printStackTrace();
}
}
imageView.setImageBitmap(bitmap);
}
}
这不就是存起来了, 然后在设置图片的时候那存起来的图片显示么
当时我就握了棵草啊...
imageView.setImageResource(R.drawable.ic_launcher)
这不香?非要存起来?真是搞不懂为什么要脱了裤子放屁,又不是网络下载的图片,本地的有必要?反正我是搞不懂了,
当时就测试了一下用到这个方法的地方,果不其然, 那崩溃是百分之百啊....
上头啊...又一个一个地方改,差不多一个小时之后,终于全部改完了,打包加固测试。通过...
终于可以上线了....
这里劝大家一下,不要太相信你前任的代码, 也许就有埋得坑...
虽然暂时没问题,也有可能一下子爆发....