【问题标题】:NullPointerException when running from Google Play but not from Android Studio从 Google Play 但不是从 Android Studio 运行时出现 NullPointerException
【发布时间】: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 去什么?
  • @greenapps 到真实设备或模拟器,在此之前他是直接从 Android Studio 做的
  • 如果您想查看从 Firebase 实时数据库获取数据并使用 FirebaseRecyclerAdapter 将其显示在 RecyclerView 中的正确方法,this 就是您的方式可以的。
  • 您应该使用 firebase-ui-database:3.3.1 以与 Firebase SDK 15.0.0 兼容。

标签: android firebase firebase-realtime-database firebaseui


【解决方案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 时却不行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    相关资源
    最近更新 更多