我的 Android 应用程序中有一个视频 Activity 。 在禁用 proguard 的调试构建中,一切都像一个魅力。 但是在启用混淆器并且视频 Activity 开始的发布版本中,我得到了一个 NPE。
我的 gradle 文件的一部分:
buildTypes {
debug {
applicationIdSuffix '.dev'
versionNameSuffix '-dev'
minifyEnabled false
shrinkResources false
}
release {
minifyEnabled true
shrinkResources true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
异常(exception):
java.lang.RuntimeException: Unable to start activity ComponentInfo{ua.com.tv24.news/ua.com.tv24.news.ui.activities.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
at ua.com.tv24.news.ui.fragments.a.b.a(Unknown Source)
at android.support.v4.app.Fragment.i(Unknown Source)
at android.support.v4.app.u.a(Unknown Source)
at android.support.v4.app.u.a(Unknown Source)
at android.support.v4.app.u.a(Unknown Source)
at android.support.v4.app.u.j(Unknown Source)
at android.support.v4.app.p.onCreate(Unknown Source)
at android.support.v7.app.ActionBarActivity.onCreate(Unknown Source)
at ua.com.tv24.news.ui.activities.a.onCreate(Unknown Source)
at ua.com.tv24.news.ui.activities.b.onCreate(Unknown Source)
at ua.com.tv24.news.ui.activities.MainActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
还有我的 Activity :
package ua.com.tv24.news.ui.activities;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.FrameLayout;
import com.google.android.libraries.mediaframework.exoplayerextensions.Video;
import com.google.android.libraries.mediaframework.layeredvideo.PlaybackControlLayer;
import com.google.googlemediaframework.adplayer.ImaPlayer;
import de.greenrobot.event.EventBus;
import ua.com.tv24.news.R;
import ua.com.tv24.news.events.ui.VideoPreparedEvent;
public class DashVideoActivity extends ActionBarActivity implements PlaybackControlLayer.FullscreenCallback {
private ImaPlayer imaPlayer;
private FrameLayout videoPlayerContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
setContentView(R.layout.activity_dash_video);
videoPlayerContainer = (FrameLayout) findViewById(R.id.video_frame);
Bundle bundle = getIntent().getExtras();
String videoUrl = bundle.getString(VideoActivity.VIDEO_URL_EXTRA);
String appName = getString(R.string.app_name);
//TODO get url and name from extras
VideoItem video = new VideoItem(appName, new Video(videoUrl, Video.VideoType.DASH, ""),
null);
createImaPlayer(video);
}
@Override
protected void onResume() {
super.onResume();
if (imaPlayer != null) {
imaPlayer.play();
}
}
@Override
protected void onPause() {
if (imaPlayer != null) {
imaPlayer.pause();
}
super.onPause();
}
@Override
protected void onDestroy() {
if (imaPlayer != null) {
imaPlayer.release();
}
EventBus.getDefault().unregister(this);
super.onDestroy();
}
public void createImaPlayer(VideoItem videoListItem) {
if (imaPlayer != null) {
imaPlayer.release();
}
// If there was previously a video player in the container, remove it.
videoPlayerContainer.removeAllViews();
String adTagUrl = videoListItem.adUrl;
String videoTitle = videoListItem.title;
imaPlayer = new ImaPlayer(this,
videoPlayerContainer,
videoListItem.video,
videoTitle,
adTagUrl);
imaPlayer.setFullscreenCallback(this);
Resources res = getResources();
Drawable logo = res.getDrawable(R.drawable.launcher);
imaPlayer.setLogoImage(logo);
imaPlayer.play();
}
@Override
public void onGoToFullscreen() {
}
@Override
public void onReturnFromFullscreen() {
}
public static class VideoItem implements Parcelable {
/**
* The title of the video.
*/
public final String title;
/**
* The actual content video (contains its URL, media type - either DASH or mp4,
* and an optional media type).
*/
public final Video video;
/**
* The URL of the VAST document which represents the ad.
*/
public final String adUrl;
/**
* @param title The title of the video.
* @param video The actual content video (contains its URL, media type - either DASH or mp4,
* and an optional media type).
* @param adUrl The URL of the VAST document which represents the ad.
*/
public VideoItem(String title, Video video, String adUrl) {
this.title = title;
this.video = video;
this.adUrl = adUrl;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
}
}
public void onEventMainThread(VideoPreparedEvent event) {
View progress = findViewById(R.id.videoLoaderBar);
if (progress != null) {
progress.setVisibility(View.INVISIBLE);
}
}
}
还有我的proguard规则:
-dontwarn com.google.android.gms.**
# Picasso
-dontwarn com.squareup.okhttp.**
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
#okhttp
-keepnames class com.levelup.http.okhttp.** { *; }
-keepnames interface com.levelup.http.okhttp.** { *; }
-keepnames class com.squareup.okhttp.** { *; }
-keepnames interface com.squareup.okhttp.** { *; }
-dontwarn com.squareup.okhttp.internal.http.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
#retrofit
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.google.gson.** { *; }
-keep class com.google.inject.** { *; }
-keep class org.apache.http.* { *; }
-keep class org.apache.james.mime4j.* { *; }
-keep class javax.inject.** { *; }
-dontwarn rx.*
-keep class com.example.testobfuscation.** { *; }
-keepattributes Signature
-keep class sun.misc.Unsafe { *; }
-keep class retrofit.** { *; }
-keep interface retrofit.** { *; }
-keepclasseswithmembers class * {
@retrofit.http.* <methods>;
}
-keepclasseswithmembers class * {
@ua.* <methods>;
}
-dontwarn retrofit.appengine.**
-keep class ua.com.tv24.news.models.** { *; }
-keepattributes InnerClasses
#xml parser
-keep interface org.simpleframework.xml.** { *; }
-keep class org.simpleframework.xml.** { *; }
#eventBus
-keepclassmembers class ** {
public void onEvent(**);
}
-keepclassmembers class ** {
public void onEventMainThread(**);
}
#support v7
-keep class android.support.v7.** { *; }
#unusage classes
-dontwarn retrofit.appengine.UrlFetchClient
-dontwarn retrofit.RxSupport$1
-dontwarn com.google.ads.a.a
-dontwarn com.google.ads.a.c
-dontwarn com.google.ads.a.d
-dontwarn com.google.ads.a.f
-dontwarn com.google.android.exoplayer.hls.HlsMediaPlaylistParser
-dontwarn okio.DeflaterSink
-dontwarn org.simpleframework.xml.stream.StreamProvider
-dontwarn okio.Okio
-dontwarn org.simpleframework.xml.stream.StreamReader
-dontwarn org.simpleframework.xml.stream.StreamReader$Entry
-dontwarn org.simpleframework.xml.stream.StreamReader$Start
-dontwarn org.simpleframework.xml.stream.StreamReader$Text
-dontwarn retrofit.RestMethodInfo$RxSupport
-dontwarn retrofit.RxSupport
-dontwarn retrofit.RxSupport$2
最佳答案
请注意您已将类和方法排除在 ProGuard 处理之外:
# Hide warnings about references to newer platforms in the library
-dontwarn android.support.v7.**
# don't process support library
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
如果Reflection,通常会发生错误。之所以涉及,是因为 Proguard 在这种情况下无法解析依赖关系。
我只是看到您错过了 ProGuard 文件中的接口(interface)(作为异常(exception)):
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ...
关于android - Proguard收缩导致空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29666634/
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame
我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是
我们如何捕获或/和处理ruby中所有未处理的异常?例如,这样做的动机可能是将某种异常记录到不同的文件或发送电子邮件给系统管理。在Java中我们会做Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandlerex);在Node.js中process.on('uncaughtException',function(error){/*code*/});在PHP中register_shutdown_function('errorHandler');functionerrorHandler(){$error=error_
如何在出现异常时指定全局救援,如果您将Sinatra用于API或应用程序,您将如何处理日志记录? 最佳答案 404可以在not_found方法的帮助下处理,例如:not_founddo'Sitedoesnotexist.'end500s可以通过调用带有block的错误方法来处理,例如:errordo"Applicationerror.Plstrylater."end错误的详细信息可以通过request.env中的sinatra.error访问,如下所示:errordo'Anerroroccured:'+request.env['si
下面的代码工作正常:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson)do|key,oldv,newv|ifkey==:aoldvelsifkey==:bnewvelsekeyendendputskerson.inspect但是如果我在“ifblock”中添加return,我会得到一个错误:person={:a=>:A,:b=>:B,:c=>:C}berson={:a=>:A1,:b=>:B1,:c=>:C1}kerson=person.merge(berson