In android versions earlier than Lollipop, I keep getting the VerifyError while trying to instantiate a fragment, leading to an app crash. Can someone explain to me the cause of this error?
12-19 17:46:52.510 28238-28238/com.greeblu.tootl2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.greeblu.tootl2, PID: 28238
java.lang.VerifyError: com/greeblu/tootl2/fragment/ProfileGridFragment
at com.greeblu.tootl2.activity.ProfileActivity.launchGridFragment(ProfileActivity.java:289)
at com.greeblu.tootl2.fragment.ProfileOverlayFragment$3.onClick(ProfileOverlayFragment.java:123)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18439)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5034)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
at dalvik.system.NativeStart.main(Native Method)
This is how I'm calling the fragment for older android versions:
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.profileContainer, new ProfileGridFragment(),fragmentTag); //Replaces the Fragment C previously in the right_container with a new Fragment B
ft.commit();
Edit:
The code for the onClick call is as follows. It is called from another fragment in the same activity
picContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((ProfileActivity) getActivity()).launchGridFragment(overlayDp, "all");
}
});
I've encountered this exact error because I had a try-catch block with exception class that is unavailable on old android versions. The block wasn't even in the constructor, it was in one of the onClick methods so the code wasn't even executed, but nevertheless app was always crashing with VerifyError as soon as I was trying to create the fragment.
Solver it by changing clause block with instanceof check:
Crashing:
try {
...
} catch (FileUriExposedException e) {
...
}
Works ok:
try {
...
} catch (Exception e) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && e instanceof FileUriExposedException) {
...
}
}
Are you using the support Fragment class from android.support.v4.app.Fragment? If so you need to be calling
getSupportFragmentManager()
instead of
getFragmentManager()
Note that the Fragment class from android.app.Fragment is now deprecated.
Related
I am new to android studio and I am trying to build a Notepad app.
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String title = findViewById(R.id.textView3).toString();
String note_content = findViewById(R.id.textView).toString();
FileOutputStream outputStream;
try
{
outputStream = openFileOutput(title, Context.MODE_PRIVATE);
outputStream.write(note_content.getBytes());
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
MainActivity mainActivity = new MainActivity(title);
}
});
This is the button a user clicks to save the note. Once the code saves the note, it should send the Title to MainActivity so that it can be sent to Recycleview Adapter - this will display it in viewholder as a text.
Presently, when I run the code, it crashes - however, when I remove the constructor, the app works fine.
( MainActivity mainActivity = new MainActivity(title);)
Error:
10-02 02:39:13.822 27279-27279/? D/AndroidRuntime: Shutting down VM
10-02 02:39:13.824 27279-27279/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.quicknote, PID: 27279
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.quicknote/com.example.quicknote.MainActivity}: java.lang.InstantiationException: java.lang.Class<com.example.quicknote.MainActivity> has no zero argument constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2337)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.quicknote.MainActivity> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1090)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
10-02 02:39:20.081 27279-27279/com.example.quicknote I/Process: Sending signal. PID: 27279 SIG: 9
As per the error message:
java.lang.InstantiationException: java.lang.Class has no zero argument constructor
A zero argument constructor is required for the Android system to instantiate an Activity. You should never be manually calling an Activity constructor yourself since only the system can properly create an Activity.
The Parcelables and Bundles documentation details the correct way of sending information to an Activity using the extras Bundle.
Unable to instantiate activity. Because you can't start an activity like this. You have to use intent to start activity. To sent "title" use intent extra.
Intent intent=new Intent(CurrentActivity.this, NewActivty.this);
intent.putExtra("title", title);
startActivty(intent);
Is your Activity in your AndroidManifest.xml?
If it is, you have to retrieve the title from your extras from onCreate() of MainActivity instead from the constructor.
Something like that:
//that code instead of your MainActivity mainActivity = new MainActivity(title); line
Intent intent = new Intent(YourActualActivity.this, MainActivity.class);
intent.putExtra("title", title);
startActivity(intent);
//That code in the onCreate method of your MainActivity
Bundle extras = getIntent().getExtras();
if (extras != null) {
String title = extras.getString("title");
}
I have tried the following code,
try {
final Activity activity = ctx;
FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
android.app.Fragment prev = activity.getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
DialogServiceFailed newFragment = DialogServiceFailed.newInstance(pageName, onServiceFailed);
newFragment.show(ft, "dialog");
ft.addToBackStack(null);
ft.commitAllowingStateLoss();
} catch (ClassCastException e) {
Log.d("Log", "Can't get the fragment manager with this");
}
But I get the following exception and my app crashes.
java.lang.IllegalStateException: commit already called
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:582)
at android.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
at com.brightspot.extrain5psim.model.APIRequestHandler.loadServiceFailedDialog(APIRequestHandler.java:99)
at com.brightspot.extrain5psim.view.fragments.LoginFragment.setOnAsyncTaskCompleted(LoginFragment.java:201)
at com.brightspot.extrain5psim.model.APIRequestHandler.onPostExecute(APIRequestHandler.java:80)
at com.brightspot.extrain5psim.model.APIRequestHandler.onPostExecute(APIRequestHandler.java:17)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5317)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)
newFragment.show(ft, "dialog")
show calls internally commit. So you probably want get rid of
ft.commitAllowingStateLoss();
or you can get rid of
newFragment.show(ft, "dialog");
add call
ft.add(newFragment, "dialog");
ft.commitAllowingStateLoss();
Edit
this is what DialogFragment's show() looks like
public int show(FragmentTransaction transaction, String tag) {
mDismissed = false;
mShownByMe = true;
transaction.add(this, tag);
mViewDestroyed = false;
mBackStackId = transaction.commit();
return mBackStackId;
}
My STACK_TRACE when I came back to FragmentActivity from another activity.
I searched lot for how to solve this, and I found a clue that I need to save state of fragment.
But in that clue article said, when I use FragmentPagerAdapter, I do not need to save state.
So, I confussed. Am I use FragmentPagerAdapter correctly?
Please Help me...
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test20140320/com.example.test20140320.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2308)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2362)
at android.app.ActivityThread.access$700(ActivityThread.java:168)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1329)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.test20140320.MainActivity_Fragment_Tab_02.<init>(MainActivity_Fragment_Tab_02.java:98)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1130)
at android.support.v4.app.Fragment.instantiate(Fragment.java:402)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1801)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:213)
at com.example.test20140320.MainActivity.onCreate(MainActivity.java:47)
at android.app.Activity.performCreate(Activity.java:5372)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
... 11 more
java.lang.NullPointerException
at com.example.test20140320.MainActivity_Fragment_Tab_02.<init>(MainActivity_Fragment_Tab_02.java:98)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1130)
at android.support.v4.app.Fragment.instantiate(Fragment.java:402)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:97)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1801)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:213)
at com.example.test20140320.MainActivity.onCreate(MainActivity.java:47)
at android.app.Activity.performCreate(Activity.java:5372)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2362)
at android.app.ActivityThread.access$700(ActivityThread.java:168)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1329)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5493)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
at dalvik.system.NativeStart.main(Native Method)
at com.example.test20140320.MainActivity_Fragment_Tab_02.<init>(MainActivity_Fragment_Tab_02.java:98)
My code:
public MainActivity_Fragment_Tab_02()
{
super();
mContext = getActivity().getApplicationContext(); //This is line 98
tab2 = this;
}
I think the cause is at savedInstanceState, but don't know how, and how, and how....
Below is what i use FragmentPagerAdapter.
I think this is the most doubtful part.
public class SectionsPagerAdapter extends FragmentPagerAdapter
{
public SectionsPagerAdapter(FragmentManager fm)
{
super(fm);
}
#Override
public Fragment getItem(int position)
{
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
switch(position)
{
case 0:
Fragment fragment_tab1 = new MainActivity_Fragment_Tab_02(getApplicationContext());
fragment_tab1.setRetainInstance(true);
return fragment_tab1;
case 1:
Fragment fragment_tab2 = new MainActivity_Fragment_Tab_01(getApplicationContext());
fragment_tab2.setRetainInstance(true);
return fragment_tab2;
case 2:
Fragment fragment_tab3 = new MainActivity_Fragment_Tab_03(getApplicationContext());
fragment_tab3.setRetainInstance(true);
return fragment_tab3;
}
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
Is this code leaky??
Am I use FragmentPagerAdapter correctly? OTL....
How can I fix it....?
Please Help me!
P.S. First create fragmentActivity is successful.
Move
mContext = getActivity().getApplicationContext();
to onAttached or onActivityCreated
The problem with your code is that your activity is crashing some where else and hence you are not able to get activity reference in your fragment class. Go through the stack trace, the entire log, somewhere prior to the log that you have posted here, will be some other exception that is causing the activity to stop.
In order to use activity reference in the fragment class create on mActivity variable in your fragment and before using it check for NP if(mActivity!=null). Initialize mActivity in onAttached method of fragment class
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
mActivity = activity;
}
In my MainActivity I call this code to change to a new fragment, I pass a bundle with parcelable object, itemModel to the fragment:
Bundle bundle = new Bundle();
bundle.putParcelable(ItemModel.ParcelableKey, itemModel);
fragment = new AppFragment();
fragment.setArguments(bundle);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frame_container, fragment).addToBackStack(null).commit();
In the fragment, I receive the parcel back like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mItemModel = getArguments().getParcelable(ItemModel.ParcelableKey);
//....other code.....
}
When I test it locally, the code works fine on my test device, mItemModel is able to be retrieved back properly, however, I have integrated crash report system into the app (Crashlytics), and the report states a log like this on a release:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.temp.test/com.temp.test.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
at android.app.ActivityThread.access$700(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4960)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.NullPointerException
at android.os.Parcel.readStringArray(Parcel.java:931)
at com.temp.test.data.ItemModel.<init>(ItemModel.java:478)
at com.temp.test.data.ItemModel.<init>(ItemModel.java:23)
at com.temp.test.data.ItemModel$1.createFromParcel(ItemModel.java:445)
at com.temp.test.data.ItemModel$1.createFromParcel(ItemModel.java:443)
at android.os.Parcel.readParcelable(Parcel.java:2103)
at android.os.Parcel.readValue(Parcel.java:1965)
at android.os.Parcel.readMapInternal(Parcel.java:2226)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1165)
at com.temp.test.fragments.AppFragment.onCreateView(AppFragment.java:98)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
at android.app.FragmentManagerImpl.moveTo## Heading ##State(FragmentManager.java:1035)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1017)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1804)
at android.app.Activity.performCreate(Activity.java:5206)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
at android.app.ActivityThread.access$700(ActivityThread.java:143)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4960)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(NativeStart.java)
at com.temp.test.fragments.AppFragment.onCreateView(AppFragment.java:98) <-- This error line leads to this line in the source code:
mItemModel = getArguments().getParcelable(ItemModel.ParcelableKey);
It is very strange because it works well in my local device. So I dived a little deeper into Bundle's source code, I noticed that in unparcel(), it has a checking like this at the beginning:
synchronized void unparcel() {
if (mParcelledData == null) {
if (DEBUG) Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this)) + ": no parcelled data");
return;
}
//....other code.....
}
The strange thing is that mParcelledData should be null in my case, because I created Bundle like this Bundle bundle = new Bundle(); as shown in my code snippet above, so in my case it should be using mMap instead of mParcelledData.
Question: what are the possible cases that getArguments() in fragment's onCreateView() will return a Bundle with non-null mParcelledData?
OR
In what cases that mItemModel = getArguments().getParcelable(ItemModel.ParcelableKey); will perform differently in my local test device vs production release for end user?
excuse the trouble I was trying to make a listview for parsing a page for my app, I'll explain: I have a actionbar formed by Fragment.
When instazia the fragment, opening the app the first time "getActivity" does not return null, is the next time, when I start the AsyncTask
In the fragment in which I will stop parsing this error:
java.lang.NullPointerException
at android.widget.ArrayAdapter.init(ArrayAdapter.java:310)
at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:104)
at com.megadown.megacodownloader.ParsingArrayAdapter.<init>(ParsingArrayAdapter.java:30)
at com.megadown.megacodownloader.Tab_Search$ParsingPaginaWeb.onPostExecute(Tab_Search.java:264)
at com.megadown.megacodownloader.Tab_Search$ParsingPaginaWeb.onPostExecute(Tab_Search.java:125)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
Code Java that refers:
protected void onPostExecute(String result)
{
// dopo che ho eseguito il parsing mostro i dati nella listview
adapter = new ParsingArrayAdapter(myActivity, titoli, descrizioni,immagini);
lista.setAdapter(adapter);
}
If you want I can post the code of the ArrayAdapter.
Thank you in advance
First, make sure myActivity has the correct value:
protected void onPostExecute(String result) {
Activity myActivity = getActivity();
adapter = new ParsingArrayAdapter(myActivity, titoli, descrizioni,immagini);
lista.setAdapter(adapter);
}
Next, point is, you can't be sure that your activity and fragment is still active in onPostExecute().
For example, the user could have pressed 'back' button or rotated the screen, which would re-create the activites and fragments.
So, the good code is:
protected void onPostExecute(String result) {
Activity myActivity = getActivity();
if (myActivity==null) return; // Fragment not active anymore, bail out
adapter = new ParsingArrayAdapter(myActivity, titoli, descrizioni,immagini);
lista.setAdapter(adapter);
}
Fragment's getActivity() will only return expectable value while the associated activity has done onCreate method.