skip to Main Content

I’m developing my application in Android Studio.
Today, I need to upgrade to API33.
Application compilation: OK

Test on my phone :

  • Opening : OK
  • Navigation inside: OK
  • Fragments navigation : Application crash

It’s worth noting that during development, I ignored compilation errors:
"This fragment should provide a default constructor (a public constructor with no arguments)" and "Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead" by adding:

lintOptions {
disable ‘ValidFragment’
}

to Gradle. On all Android versions, the application works well except for Api 30 and above.

And what’s confusing me is that the application compiled with Api 28 and 29 runs smoothly on all versions of Android 11, 12 and 13. But unfortunately, I have to compile with API33 for Google.

Can you suggest a solution? Or is there an other statement to replace the LintOptions ?

Here’s the code for one of my fragments:

package com.XXXXXXXX.XXXXX;

import android.app.Activity;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

public class HelloFragment extends Fragment {

    ListView lst;
    String[] maladie = {"Michel","Jack"};


    String[] desc = {"Acheteur","Vendeur"};
       


    Integer[] imgid = {R.drawable.michel,R.drawable.jack};

    Activity mainActivity;
    public HelloFragment(Activity main){
        this.mainActivity = main;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.hello_fragment, container, false);


        lst = view.findViewById(R.id.listviewhello);
        CustomeListviewAdapter customeListview = new CustomeListviewAdapter(this.mainActivity,maladie,desc,imgid);
        lst.setAdapter(customeListview);

        lst.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                if(position == 0) {
                    Intent intent = new Intent(getContext(),Michel.class);
                    startActivity(intent);
                }if(position == 1) {
                    Intent intent = new Intent(getContext(),Jack.class);
                    startActivity(intent);
                }


            }
        });
        return view;
    }
}

I call from a Home Class :

helloFragment = inflate.findViewById(R.id.home_hello);
     helloFragment.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View view) {
             HelloFragment nextFrag= new HelloFragment(getActivity());
             getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, nextFrag,"findThisFragment").addToBackStack(null).commit();
         }
     });

Here is on my Gradle :

apply plugin: 'com.android.application'

android {
    signingConfigs {
        Signer {
            keyAlias 'ssa_key'
            keyPassword 'XXXXX'
            storeFile file('C:/Users/David/AndroidStudioProjects/ssa_keys.jks')
            storePassword 'YYYYYYY'
        }
    }
    lintOptions {
        disable 'ValidFragment'
    }


    compileSdkVersion 33
    defaultConfig {
        applicationId 'com.XXXXXXXXX.XXXXXXX'
        minSdkVersion 17
        targetSdkVersion 33
        versionCode 14
        versionName "3.3"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        signingConfig signingConfigs.Signer
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.Signer
        }
    }
    productFlavors {
    }
    buildToolsVersion '34.0.0'
}


dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    //noinspection GradleCompatible
    implementation 'com.android.support:appcompat-v7:26.1.0'
    //noinspection GradleCompatible
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16'
}

I’ve already tried to compile on several SDK versions 26 to 33, but the same.

2

Answers


  1. the position is within the bounds of your data (assuming yourDataList is the list you are displaying in the ListView). If the position is out of bounds, you can either handle it as needed or simply ignore it. This will help prevent a crash when an invalid position is clicked.

    you can use getApplication() instead of getContext() application is more safe.

    checkout this

            lst.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                    // Check if the position is within the bounds of your data
                    if (position >= 0 && position < yourDataList.size()) {
                        // Create an intent based on the clicked item
                        Intent intent;
                        if (position == 0) {
                            intent = new Intent(/* you can use getApplication()*/getContext(), Michel.class);
                        } else if (position == 1) {
                            intent = new Intent(/* you can use getApplication()*/getContext(), Jack.class);
                        } else {
                            // Handle other positions or show a message that the option is not available
                            // You can also log an error here
                            return;
                        }
    
                        startActivity(intent);
                    }
                }
            });
    
    Login or Signup to reply.
  2. The issue you are experiencing with fragments on Android API 30 and above is likely related to changes in the way Android handles fragment instantiation. Starting with Android API 28, there is a requirement for fragments to have a default, no-argument constructor. This is enforced by Android, and your code does not adhere to this requirement. Disabling lint checks is not a recommended solution because it does not fix the underlying issue.

    To resolve this issue, you should modify your fragment classes to follow Android’s guidelines for fragment construction. Here’s how you can do that:

    1. Create a default constructor in your fragment class, alongside the existing constructor with parameters.
    public class HelloFragment extends Fragment {
        // Existing code...
    
        public HelloFragment() {
            // Required empty public constructor.
        }
    
        // Parameterized constructor.
        public HelloFragment(Activity main) {
            this.mainActivity = main;
        }
        
        // Rest of your code...
    }
    
    1. Instead of passing the Activity as a parameter, use getActivity() within the fragment to obtain a reference to the hosting activity.
    public class HelloFragment extends Fragment {
        // Remove the parameterized constructor.
    
        // Rest of your code...
    }
    
    1. To pass data or configuration to your fragment, use the setArguments(Bundle args) method.

    Here’s how you can modify your fragment instantiation code:

    helloFragment = inflate.findViewById(R.id.home_hello);
    helloFragment.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            HelloFragment nextFrag = new HelloFragment();
            // Create and set arguments if needed.
            Bundle args = new Bundle();
            args.putString("key", "value");
            nextFrag.setArguments(args);
    
            getActivity().getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment_container, nextFrag, "findThisFragment")
                .addToBackStack(null)
                .commit();
        }
    });
    

    By making these changes, your fragments should be compatible with Android 30 and above. Please ensure you update any other fragments in a similar manner. Disabling lint checks is not recommended because it won’t address the underlying compatibility issues with newer Android versions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search