从 Google Play 但不是从 Android Studio 运行时出现 NullPointerException
Posted
技术标签:
【中文标题】从 Google Play 但不是从 Android Studio 运行时出现 NullPointerException【英文标题】:NullPointerException when running from Google Play but not from Android Studio 【发布时间】:2018-10-05 23:05:54 【问题描述】:我遇到了一个大问题,我不知道发生了什么,我已经将一个应用程序上传到 Play 商店,因为当我在模拟器甚至我的真实设备上运行它时,它并没有崩溃,但是现在当我从 Google Play 下载它时,它说:
java.lang.NullPointerException:
at com..onBindViewHolder (ChooseCard.java)
or .onCreateViewHolder (ChooseCard.java)
at com..onBindViewHolder (ChooseCard.java)
or .onCreateViewHolder (ChooseCard.java)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItemCount (FirebaseRecyclerAdapter.java)
or .onBindViewHolder (FirebaseRecyclerAdapter.java)
or .onChildChanged (FirebaseRecyclerAdapter.java)
or .onError (FirebaseRecyclerAdapter.java)
at com.yarolegovich.discretescrollview.InfiniteScrollAdapter.access$100 (InfiniteScrollAdapter.java)
or .getItemCount (InfiniteScrollAdapter.java)
or .getItemViewType (InfiniteScrollAdapter.java)
or .onAttachedToRecyclerView (InfiniteScrollAdapter.java)
or .onBindViewHolder (InfiniteScrollAdapter.java)
or .onCreateViewHolder (InfiniteScrollAdapter.java)
or .wrap (InfiniteScrollAdapter.java)
这个问题已经好几天了,我找不到它,请你帮帮我吗?
这是我的build.gradle
实现
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:design:27.1.1'
implementation 'com.intuit.sdp:sdp-android:1.0.4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.google.firebase:firebase-core:15.0.0'
implementation 'com.google.firebase:firebase-auth:15.0.0'
implementation 'com.google.android.gms:play-services-auth:15.0.0'
implementation 'com.google.firebase:firebase-database:15.0.0'
implementation 'com.anjlab.android.iab.v3:library:1.0.44'
implementation 'com.firebaseui:firebase-ui-database:3.3.1'
implementation 'com.onesignal:OneSignal:3.7.1'
implementation 'com.yarolegovich:discrete-scrollview:1.3.2'
implementation 'com.pranavpandey.android:dynamic-toasts:0.9.0'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.11'
implementation 'com.google.android.gms:play-services-analytics:15.0.0'
.....
dependencies
classpath 'com.android.tools.build:gradle:3.1.2'
classpath 'com.google.gms:google-services:3.2.1'
编辑
我已经在 Google Play 上更新了我的应用程序,但没有任何反应,仍然在同一个 Activity
上崩溃,我现在知道如何调试它,问题是当我在模拟器上从 Google Play 下载应用程序时(即使在新的模拟器设备上也不会崩溃)和在我的真实设备上。
正如@Marcos Vascondelos 所说,我做了 Build > Genreate Signed APK > get the app-release.apk 在我的设备上安装它,问题是我无法登录它是这个方法:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN)
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try
// Google Sign In was successful, authenticate with Firebase
GoogleSignInAccount account = task.getResult(ApiException.class);
firebaseAuthWithGoogle(account);
catch (ApiException e)
// Google Sign In failed, update UI appropriately
Log.w(TAG, "Google sign in failed", e.getCause());
Toast with e.getCause is null
如果你想看看我如何登录而不是在这个问题上添加更多代码,我在这个GitHubGist
我读过可能是 SHA-1 的问题,但我不知道为什么在模拟器上没问题,设备没问题,Google play 也没问题,但是如果我直接安装 .apk,它会显示为空。
最后编辑
我发现问题不在Firebase
调用上,而是在填充列表上,我的意思是产品被正确捕获,但是当我尝试放入列表时它崩溃了
我的FirebaseRecyclerOptions
适配器看起来像
final FirebaseRecyclerOptions< CardPOJO > options =
new FirebaseRecyclerOptions.Builder< CardPOJO >()
.setQuery(products_ref, CardPOJO.class)
.build();
adapter = new FirebaseRecyclerAdapter< CardPOJO, CardHolder>(options)
@Override
public CardHolder onCreateViewHolder(ViewGroup parent, int viewType)
//inflate the single recycler view layout(item)
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_product, parent, false);
final CardHolder cardViewHolder = new CardHolder(view);
return cardViewHolder;
@Override
public void onDataChanged()
super.onDataChanged();
if(progressDialog!=null)progressDialog.dismiss();initViews();
@Override
protected void onBindViewHolder(final CardHolder holder, int position, final CardPOJO model)
holder.itemView.setSelected(0== position); ////where you are in the list
holder.getLayoutPosition();
switch (model.getState())
case "free":
holder.card_image.setImageResource();
break;
case "not_free":
if(userOwnsProduct(model.getProduct_id()))
holder.card_image.setImageResource();
else
holder.card_image.setImageResource();
break;
default:
break;
holder.view.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if(model.getState().equals("free"))
//normal stuff1
else
if (!readyToPurchase)
DynamicToast.makeError(mContext,"Problems with Google Play",Toast.LENGTH_SHORT).show();
return;
root_ref.child("PurchasedProducts").child(currentUser).addValueEventListener(new ValueEventListener()
@Override
public void onDataChange(DataSnapshot dataSnapshot)
if(dataSnapshot.hasChild(model.getProduct_id()))
//Normal stuff
else
bp.purchase((Activity) mContext,model.getProduct_id());
@Override
public void onCancelled(DatabaseError databaseError)
);
);
;
adapter.startListening();
infiniteAdapter = InfiniteScrollAdapter.wrap(adapter);
itemPicker.setAdapter(infiniteAdapter);
//.setItemTransitionTimeMillis(DiscreteScrollViewOptions.getTransitionTime());
itemPicker.setItemTransformer(new ScaleTransformer.Builder()
.setMinScale(0.5f)
.build());
【问题讨论】:
but now when I download it from Google Play
去什么?
Have a look at this thread
@greenapps 到真实设备或模拟器,在此之前他是直接从 Android Studio 做的
如果您想查看从 Firebase 实时数据库获取数据并使用 FirebaseRecyclerAdapter
将其显示在 RecyclerView
中的正确方法,this 就是您的方式可以的。
您应该使用 firebase-ui-database:3.3.1 以与 Firebase SDK 15.0.0 兼容。
【参考方案1】:
记住,总是检查组件是否为空。比执行你的代码。 示例:
if ("your_component" != null)
//your code
【讨论】:
【参考方案2】:您似乎已经尝试了我能想到的几乎所有方法。这可能是 SHA-1 的问题。试试这些:
首先,检查你正在访问的孩子是否真的存在。(即不为空) 尝试检查您是否确实有权添加产品。另外,请检查 Firebase 规则。 尝试添加具有不同类型用户的产品(如果您的应用包含不同类型的用户)。【讨论】:
测试它并且它工作......问题是尝试将数据放入recyclerView时 @IshanFernando 我猜有问题,否则我会再次上传 @IshanFernando 用适配器代码编辑了我的问题 @Skizo-ozᴉʞS 你能告诉我们它崩溃的地方吗?如果没有,那很好。还有一件事:在模型上调用 get 方法之前,您是否可以检查是否设置了产品详细信息和 id?【参考方案3】:好的,这就去!我看到代码有一个异常可能被忽略,就像在高端 apis 中一样。简单来说,api 23 和 >23 就像在 viewHolder 区域中使用 ViewGroup Parent 获取上下文一样!没问题,但在小型 api 设备上我认为这将是一个问题!
所以试试这个希望这会有所帮助!
也许我是从这个角度看的,希望对你有帮助
public CardHolder onCreateViewHolder(ViewGroup parent, int viewType)
//inflate the single recycler view layout(item)
// !!!!!!!!!!!!! **the issue is here**! !!!!!!!!!!!!!!!
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_product, parent, false);
final CardHolder cardViewHolder = new CardHolder(view);
return cardViewHolder;
您的布局没有正确膨胀!像这样获取上下文可能是该类出现NULL POINTER EXCEPTION的原因!有一个简单的方法来做到这一点!比如通过在实例化时使用适配器的构造函数获取活动的上下文。
这是一个例子!
public class yourActivity extends AppCompatActivity
YourAdapter mAdapter;
/// lets say you are setting it up in android ONCREATE Method
@override
public void OnCreate(....)
...........
mAdapter(data,design,YourActivity.this);
//here this will be the context going in your adapter simple
在您的适配器的构造函数中,您可以将其存储在一个全局变量中,可能是这样的
public class YourAdapter extends RECYCLERView.Adapter......
Context mContext;
public YourAdapter(Data data, int design,Context mContext)
this.mContext = mContext;
//and now you can access without any stress about context null exception
public CardHolder onCreateViewHolder(ViewGroup parent, int viewType)
//inflate the single recycler view layout(item)
View view = LayoutInflater.from(mContext)
.inflate(R.layout.card_product, parent, false);
final CardHolder cardViewHolder = new CardHolder(view);
return cardViewHolder;
上面的代码暴露并解决了第一个异常。我希望的第二个是这样的
您正在尝试使用 RecyclerView,但没有为它提供用于保存视图的子类!
当我们为回收器视图制作适配器时,必然会有 ViewHolder 的子类为我们做简单的回收。该子类的主要工作是保存视图并使用它们的 id 找到它们
对于一般示例,试试这个 link 我找到了!归功于 git writer。
【讨论】:
所以你说的是两种方法,对吧? parent.getContext() 并将上下文本身传递给构造函数? parent.getContext 不起作用,这是这里异常的主要原因!尝试改变获取上下文的方式,我希望会奏效 但是我有这样的适配器: adapter = new FirebaseRecyclerAdapter(options) @Override public CardHolder onCreateViewHolder(ViewGroup parent, int viewType) //膨胀单个回收器视图布局( item) 视图视图 = LayoutInflater.from(parent.getContext()) .inflate(R.layout.card_product, parent, false);返回新的持卡人(视图); 如何通过参数传递上下文? 创建一个新类扩展它的 FirebaseRecyclerAdapter 并尝试在那里创建构造函数^_^【参考方案4】:问题是在使用Proguard
时,我没有在我的pojo 类上使用@Keep
,所以当尝试使用firebase
序列化类时,数据库没有找到属性,因为它们被混淆了。
【讨论】:
我面临着完全相同的问题。你在哪里使用@Keep?在使用 firebase 数据库的整个 Fragment 上? 欢迎提出新问题并添加信息,以便我查看:) 同样的问题!!我试图从 wordpress 获取数据,它可以在我的手机上运行(从我的笔记本电脑上运行时),但当我将其上传到 Google Play 时却不行以上是关于从 Google Play 但不是从 Android Studio 运行时出现 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章
如何知道应用程序是从 google play 还是侧载安装的?