Conductor - Controller Pager Adapter | Out of memory crash - java

I recently made an app with a ViewPager and my child fragments weren't being destroyed properly causing out of memory exception. I fixed it by using this https://github.com/adamsp/FragmentStatePagerIssueExample/blob/master/app/src/main/java/com/example/fragmentstatepagerissueexample/app/FixedFragmentStatePagerAdapter.java
Now I have rebuilt my app to use Controllers instead of fragments and things got messy. The Conductor library has official support of ViewPager via ControllerPagerAdapter, but it seems as broken as the original android one. Here's my code:
I make the adapter in PagerController:
PagerAdapter adapter = new PagerViewAdapter(this, pdfFactory.getPageCount());
PagerViewAdapter:
public class PagerViewAdapter extends ControllerPagerAdapter {
private final int size;
public PagerViewAdapter(Controller controller, int size) {
super(controller, false);
this.size = size;
}
#Override
public int getCount() {
return size;
}
#Override
public Controller getItem(int position) {
return new PagerImageController(position);
}
}
PagerImageController:
public class PagerImageController extends Controller {
#Inject PdfFactory pdfFactory;
private int position;
public PagerImageController() {}
public PagerImageController(int position) {
this.position = position;
setRetainViewMode(RetainViewMode.RELEASE_DETACH);
Log.d("LOG", "PagerImageController: "+position);
}
#NonNull
#Override
protected View onCreateView(#NonNull LayoutInflater inflater, #NonNull ViewGroup container) {
//Dagger 2
((CorePdfApplication) getActivity().getApplication()).getComponent().inject(this);
//Locate and inflate the PhotoView
final View v = inflater.inflate(R.layout.pager_element, container, false);
PhotoView photoView = (PhotoView) v.findViewById(R.id.pager_image);
Observable.just(position)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(integer -> {
photoView.setImageBitmap(pdfFactory.getPage(integer));
})
.subscribe();
return v;
}
}
LOG:
java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:114)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5696)
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:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 20866572 byte allocation with 16777216 free bytes and 18MB until OOM
Any ideas how to fix this one?

Related

App crashes with IndexOutOfBoundsException when deleting firebase child with removeValue()

I am making an android app based on firebase Realtime database. I am reading the data in a RecyclerView. There are three items in my RecyclerView.
Text view = Name
Text view = Number
Button = Delete
When I delete some child from my RecyclerView three things can happen:
Sometimes it deletes the targeted child normally
Sometimes it deletes some other child (often which is below the targeted child.)
Sometimes my app crashes.
This is the code for my adapter:
public class holder extends RecyclerView.ViewHolder {
public Button btnDelete;
public TextView tvName;
public TextView tvRoll;
public holder(#NonNull View itemView) {
super(itemView);
btnDelete=(Button) itemView.findViewById(R.id.idDelete);
tvName=(TextView) itemView.findViewById(R.id.idName);
tvRoll=(TextView) itemView.findViewById(R.id.idRoll);
}
}
This is the code to show items in recycler view and code for delete button:
options = new FirebaseRecyclerOptions.Builder<basic>()
.setQuery(myRef, basic.class)
.build();
adapter = new FirebaseRecyclerAdapter<basic, holder>(options) {
#SuppressLint("SetTextI18n")
#Override
protected void onBindViewHolder(#NonNull holder holder, final int i, #NonNull final basic basic) {
holder.tvName.setText(basic.getFb01name());
holder.tvRoll.setText(basic.getFb04roll());
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myRef.child(getRef(i).getKey()).removeValue();
}
});
}
#NonNull
#Override
public holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
return new holder(v);
}
};
//------------------------------
adapter.startListening();
Userlist.setAdapter(adapter);
//-----------------------------------
I cannot guess where is the problem.
Please also provide a practical solution.
This is the crash report:
2020-11-30 23:27:45.968 10796-10796/com.my App Name E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.my App Name, PID: 10796
java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.get(ArrayList.java:437)
at com.firebase.ui.common.BaseObservableSnapshotArray.getSnapshot(BaseObservableSnapshotArray.java:70)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getRef(FirebaseRecyclerAdapter.java:112)
at com.my App Name.ViewActivity$1$1.onClick(ViewActivity.java:72)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2020-11-30 23:27:46.701 1467-10685/com.google.android.googlequicksearchbox E/sb.v.u.LiteSuggestSourc: On-device lite suggest model loading error.
2020-11-30 23:27:46.818 1467-1774/com.google.android.googlequicksearchbox E/MDD: DownloadProgressMonitor: Can't find file group for uri: android://com.google.android.googlequicksearchbox/files/sharedminusonemodule/shared/SharedMinusOneData.pb.tmp
It seems that when you access Firebase getRef(i) within the button onClick callback, it can reference a wrong position i causing IndexOutOfBoundsException
So, we'll get the key outside of the callback as below:
options = new FirebaseRecyclerOptions.Builder<basic>()
.setQuery(myRef, basic.class)
.build();
adapter = new FirebaseRecyclerAdapter<basic, holder>(options) {
#SuppressLint("SetTextI18n")
#Override
protected void onBindViewHolder(#NonNull holder holder, final int i, #NonNull final basic basic) {
holder.tvName.setText(basic.getFb01name());
holder.tvRoll.setText(basic.getFb04roll());
String refKey = getRef(i).getKey(); // <<<<<< Here is the change
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myRef.child(refKey)).removeValue();
}
});
}
#NonNull
#Override
public holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.items, parent, false);
return new holder(v);
}
};

Displaying images downloaded from Firebase in a GridView on a Fragment keeps crashing upon opening fragment

I am creating a gallery for our android app using a GridView on one of our fragments which are located in a navigation drawer. I created a custom adapter for the image view that uses Picasso to display the images in a Image View. I made a method called DohvatiSlike() that downloads images from firebase and saves them in a File variable. When i build the app and run it, whenever i open the gallery from the navigation drawer it crashes the app. If i exclude the line setting the GalleryGridAdapter in the onCreateView there is no crash but it obviously doesn't work. Can anyone help me find the problem?
This is the GalleryFragment code:
public class GalleryFragment extends Fragment implements NavigationItem {
private DatabaseReference mDatabaseRef;
private List<File> slike;
private int position;
GridView galleryGridView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.gallery_fragment, container, false);
super.onCreateView(inflater, container, savedInstanceState);
galleryGridView = (GridView)v.findViewById(R.id.gallery_gridview);
DohvatiSlike();
galleryGridView.setAdapter(new GalleryGridAdapter(getActivity(), slike));
return v;
}
public void DohvatiSlike(){
mDatabaseRef=FirebaseDatabase.getInstance().getReference("images");
mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot: dataSnapshot.getChildren()){
File slika = postSnapshot.getValue(File.class);
slike.add(slika);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText((AppCompatActivity)getActivity(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
}
This is the Adapter code:
public class GalleryGridAdapter extends BaseAdapter {
private Context mContext;
public List<File> slike;
public GalleryGridAdapter(Context context, List<File> slikice){
slike = slikice;
mContext = context;
}
#Override
public int getCount() {
return slike.size();
}
#Override
public Object getItem(int position) {
return slike.indexOf(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(500, 500));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else{
imageView = (ImageView) convertView;
}
Picasso.with(mContext).load(slike.indexOf(position)).into(imageView);
return imageView;
}
}
EDIT*
Here is the crash log
Process: hr.foi.air1817.botanico, PID: 26065
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at hr.foi.air1817.botanico.adapters.GalleryGridAdapter.getCount(GalleryGridAdapter.java:26)
at android.widget.GridView.setAdapter(GridView.java:211)
at hr.foi.air1817.botanico.fragments.GalleryFragment$1.onDataChange(GalleryFragment.java:62)
at com.google.firebase.database.obfuscated.zzap.zza(com.google.firebase:firebase-database##16.0.3:75)
at com.google.firebase.database.obfuscated.zzca.zza(com.google.firebase:firebase-database##16.0.3:63)
at com.google.firebase.database.obfuscated.zzcd$1.run(com.google.firebase:firebase-database##16.0.3:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6863)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I have been at this for two days straight and just can't get it to work, and advice or ideas are appreciated
This is a common problem with asynchronous operations, your code will always crash because you are setting the adapter data before it's reached from Firebase, when you do this
DohvatiSlike();
galleryGridView.setAdapter(new GalleryGridAdapter(getActivity(), slike));
the method DohvatiSlike(); is still requesting the data and may not finish adding the elements at the slike Array you have.
Instead, move the setting of the adapter inside your DohvatiSlike(); method
public void DohvatiSlike(){
slike = new List<>();
mDatabaseRef = FirebaseDatabase.getInstance().getReference("images");
mDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot: dataSnapshot.getChildren()){
File slika = postSnapshot.getValue(File.class);
slike.add(slika);
}
galleryGridView.setAdapter(new GalleryGridAdapter(getActivity(), slike));
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText((AppCompatActivity)getActivity(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
When you execute DohvatiSlike() you will need to wait depending on your internet connection to fetch that data, after that data is fetched you fill your Array, in this case you are requesting the data and immediately setting the adapter with data that might not been fetched yet, instead just set the adapter after all the data has been parsed and added inside your onDataChange.
Also, when showing views do it inside onViewCreated() because onCreateView() is just for inflating your view elements

On scroll the RecyclerView getting exception : -" java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 21"

I am using the RecyclerView with Sqlite in my app.
As i have load the RecyclerView from the SQlite and than after call service in background and try to notify the RecyclerView by notifyDataSetChanged() method but getting the unexpected exception while scrolling the RecyclerView( when RecyclerView is updating or notifying).
Please check my setAdapter() which i am using to notify and set the adapter on RecyclerView
private void setAdapter() {
if (adapter == null) {
adapter = new EmojiAdapter(stickerArrayList, getActivity(), "Sticker", stickerIdArrayList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
rvEmoji.setLayoutManager(mLayoutManager);
rvEmoji.setItemAnimator(new DefaultItemAnimator());
rvEmoji.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
}
I have tried all RecyclerView.stopScroll(), RecyclerView.getRecycledViewPool().clear() but problem is not short out
Exception
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 21(offset:21).state:32
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5546)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5482)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5478)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2215)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1542)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1502)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1316)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1061)
at android.support.v7.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:4769)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
at android.view.Choreographer.doCallbacks(Choreographer.java:574)
at android.view.Choreographer.doFrame(Choreographer.java:543)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
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:5095)
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:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
There are alots of simliar question but i am not getting the expected result.Here is the link which i have visited before posting the question here.
1. First link
2. Second link
3. Third link
4. Forth link
5. Fifth link
6. Sixth link
I have visited all the link and tried their best solutions , but it is not working for me..
I am using the following gradle version for the RecyclerView
compile 'com.android.support:recyclerview-v7:26.+'
Please check the Adapter class which i am using as follow:-
public class EmojiAdapter extends RecyclerView.Adapter<EmojiAdapter.MyViewHolder> {
private Activity activity;
private HashMap<String, ArrayList<EmojiBean>> arrayList = new HashMap<>();
private String sticker_emoji;
private ArrayList<String> keyArrayList = new ArrayList<>();
public class MyViewHolder extends RecyclerView.ViewHolder {
private RecyclerView rvItemCreation;
private TextView txtStickerName, txtBy, txtCreator;
private ImageView imgForward, imgDownload;
private MyViewHolder(View view) {
super(view);
rvItemCreation = (RecyclerView) view.findViewById(R.id.rvItemCreation);
txtStickerName = (TextView) view.findViewById(R.id.txtStickerName);
txtBy = (TextView) view.findViewById(R.id.txtBy);
txtCreator = (TextView) view.findViewById(R.id.txtCreator);
imgForward = (ImageView) view.findViewById(R.id.imgForward);
imgDownload = (ImageView) view.findViewById(R.id.imgDownload);
txtStickerName.setTypeface(Constant.setCustomFont(activity, "Montserrat-SemiBold.otf"));
txtBy.setTypeface(Constant.setCustomFont(activity, "Montserrat_Regular.otf"));
txtCreator.setTypeface(Constant.setCustomFont(activity, "Montserrat_Regular.otf"));
}
}
public EmojiAdapter(HashMap<String, ArrayList<EmojiBean>> arrayList, Activity activity, String sticker_emoji, ArrayList keyArrayList) {
this.arrayList = arrayList;
this.activity = activity;
this.sticker_emoji = sticker_emoji;
this.keyArrayList = keyArrayList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_media_item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (sticker_emoji.equalsIgnoreCase("Sticker")) {
holder.imgForward.setImageResource(R.drawable.forward_icon);
} else {
holder.imgForward.setImageResource(R.drawable.delete_icon);
}
if (arrayList.size() > position) {
MyCreationItemAdapter mAdapter = new MyCreationItemAdapter(arrayList.get(keyArrayList.get(position)), activity);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false);
holder.rvItemCreation.setLayoutManager(mLayoutManager);
holder.rvItemCreation.setItemAnimator(new DefaultItemAnimator());
holder.rvItemCreation.setAdapter(mAdapter);
}
}
#Override
public int getItemCount() {
return arrayList.size();
}
}
Please help me to short out from the problem.Thanks
Update
What i have done to resolve this conflict that I have done disable user interface(Show some progress bar) while loading the data.
I had the same question with "java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).state". This crash is show with pullrefrash , when you had loadmore the list is more than you first loaded . then you pulltorfrash new data and clear the old list data ,at this moment you adapter’s data size is not more than you new data size.
Try commenting this line of code:
rvEmoji.setItemAnimator(new DefaultItemAnimator());
Check if it works now. If it does then the error you faced is because the PredictiveAnimations are enabled. To use your code with animation you'll have to subclass the specific layout manager that you are using and override the supportsPredictiveItemAnimations() method and return false.
#Override
public boolean supportsPredictiveItemAnimations() {
return false;
}
For detailed understanding have a look here.

Attempt to get Length of null Array of file.Length()

Please Help I am newbie and I am getting am getting this error?
while I start the App, I request for Storage Permission but after that the app crashes and gives me this error :- Attempt to get Length of null Array. Please Help.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.techx.storysaver/com.techx.storysaver.MainActivity}: java.lang.NullPointerException: Attempt to get length of null array
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6126)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at com.techx.storysaver.ImageAdapter.getCount(ImageAdapter.java:40)
at android.widget.GridView.setAdapter(GridView.java:206)
at com.techx.storysaver.ImageFragment.onCreateView(ImageFragment.java:53)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2189)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2008)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1249)
at android.app.Activity.performStart(Activity.java:6696)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2628)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6126) 
at java.lang.reflect.Method.invoke(Native Method)
 
This is my ImageAdapter
public class ImageAdapter extends BaseAdapter {
private Context context;
String path = Environment.getExternalStorageDirectory().toString()+"/Pictures/";
File f = new File(path);
File file[] = f.listFiles();
public ImageAdapter(Context c)
{
context = c;
}
#Override
public int getCount() {
return file.length; //Line 40, Here i am gettin Error
}
#Override
public Object getItem(int position) {
return file[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(context);
Glide
.with( context )
.load( file[position] )
.into( imageView );
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(360,480));
return imageView;
}
}
Here is my Image Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.image_fragment, container, false);
GridView gridView = (GridView)rootView.findViewById(R.id.grid_view);
gridView.setAdapter(new ImageAdapter(getActivity())); //Line 50, Here Also i am getting Error
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(getActivity(),FullImageActivity.class);
i.putExtra("id",position);
startActivity(i);
}
});
return rootView;
}
String path = Environment.getExternalStorageDirectory().toString()+"/Pictures/";
File f = new File(path);
File file[] = f.listFiles();
The file[] is null, therefore this statement return file.length; or any other involving that variable will fail. Also do use exception handling to handle files existence in your. Like FileNotFound for example.
Also try this String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String pic_path = String.format("%s/%s",path,specific_path);
Use this instead to get a handle to the file.
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
then if(storageDir.exists()){File file[] = storageDir.listFiles();}
Syntax for calling getExternalFilesDir, it depends on a context.
getActivity().getExternalFilesDir() in Fragment
context.getExternalFilesDir() in classes, where you pass Context
as parameter
YourActivity.this.getExternalFilesDir(); when
called in inner class of Activity

Android Nullpointerexception on Recyclerview after switching fragments back and forth [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have a navigation drawer app with couple fragments. One of them utilizes recyclerviewadapter/recyclerviewholder to display items. Switching between fragments works well but AFTER switching, clicking on an item with listener causes nullpointerexception. Now, I tested it without the listener and it works fine. I'm guessing that the listener isn't refreshed? when fragment is swiping? Can someone help me out please? Been searching for days and yet I can't fix it.
Process: com.mikepenz.materialdrawer.app.debug, PID: 30803
java.lang.NullPointerException: Attempt to invoke interface method
'void
com.mikepenz.materialdrawer.app.RecyclerViewAdapter$OnItemClickListener.onItemClick(java.lang.String)'
on a null object reference
at
com.mikepenz.materialdrawer.app.RecyclerViewAdapter$1.onClick(RecyclerViewAdapter.java:43)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private List<ItemObject> itemList;
private Context context;
private OnItemClickListener listener;
public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
this.itemList = itemList;
this.context = context;
}
#Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_list, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView, context);
return rcv;
}
#Override
public void onBindViewHolder(RecyclerViewHolders holder, final int position) {
holder.countryName.setText(itemList.get(position).getName());
// holder.countryPhoto.setImageResource(itemList.get(position).getPhoto());
holder.countryName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// listener.onItemClick(itemList.get(position).getName());
Log.d("HELLO ",itemList.get(position).getName());
if (position ==1)
{
listener.onItemClick("GA");
}
}
});
}
public interface OnItemClickListener{
void onItemClick(String textName);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
#Override
public int getItemCount() {
Log.e("itemlist size ", this.itemList.size() + "");
return this.itemList.size();
}
}
replace your following code
listener.onItemClick("GA");
with
if(listener!=null){
listener.onItemClick("GA");
}
it may be work for you, may be your listener null when you try to set onItemClick

Categories