Array Adapter Crashing in Second Activity

Viewed 70

When I do listView.setAdapter(adapter) in second activity, the app crashes. Whereas if I do the same thing in the first Activity the app works fine. All the id are allocated properly to there variables.

There is one third activity where it plays the music , after clicking on the name of the music in the list view of second activity.
Now the question is why i created a second activity to display the listview, whereas i could have done it in the first activity, so here is the reason.
In the first activity , the app reads the data from the storage and makes a arraylist out of that, this takes time(like it takes 5secs to load the song and there is no display in that while), so if i am in the playing song activity and I want to go back to first activity, it will again take time to read the data from the storage, so as a result I created one more activty for just displaying the song in the list, so reading data is done only once in first activity which sends the data to the second activity in form of array. So when i press back from third activity(parent activity set as second activity ), I'll directly get the list,as the array will be already initialised in the second activity by the first activity at the starting of the app.

I haven't added a intent from second to third activity yet since the second activity is not working. But the third activity works fine because before I had only 2 activities, the first activity where it loaded the songs and also displayed the list and second activity for playing songs where it played the songs properly. Now from since I seperated the first activity into 2, I'm getting this error for listview adapter

First Activity
The listView in here, I created just for testing case,to check if the string array is proper, but the main listview in second Activity where i want to display the list, doesnt works, the app crashes, even though everything is same , obviously except for the Resourse IDs. But it doesnt crashes in this activity.


    package com.example.imusic;
    
    import androidx.annotation.NonNull;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import android.Manifest;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Environment;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Adapter;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    
    import com.karumi.dexter.Dexter;
    import com.karumi.dexter.PermissionToken;
    import com.karumi.dexter.listener.PermissionDeniedResponse;
    import com.karumi.dexter.listener.PermissionGrantedResponse;
    import com.karumi.dexter.listener.PermissionRequest;
    import com.karumi.dexter.listener.single.PermissionListener;
    
    import org.jetbrains.annotations.NotNull;
    
    import java.io.File;
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    ListView listView;
    //RecyclerView recyclerView;
    ArrayList<File> Song;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Dexter.withContext(this)
                    .withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
                    .withListener(new PermissionListener(){
                        @Override
                        public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
    //                        Toast.makeText(MainActivity.this, "Persmission Granted", Toast.LENGTH_SHORT).show();
                            Song=fetchSongs(Environment.getExternalStorageDirectory());  //gets external storage directory and passes it to the function which then return list of al songs
                           // Song=fetchSongs(Environment.getExternalStorageDirectory());  //gets external storage directory and passes it to the function which then return list of al songs
                            String []items=new String[Song.size()];//create string arr of size Song
                            for(int i=0;i<Song.size();i++){
                                items[i]=Song.get(i).getName().replace(".mp3","");// put the names of song in array and replaces .mp3 with " "
                            }
                            Intent intent=new Intent(MainActivity.this,MainActivity3.class);
                            intent.putExtra("songlist",Song);
                            intent.putExtra("stringlist",items);
                            listView=findViewById(R.id.listView);
    //                        CustomAdapter adapter=new CustomAdapter(MainActivity.this,R.layout.mylayout,items);
    //                        listView.setAdapter(adapter);
                            startActivity(intent);
    //                        Toast.makeText(MainActivity.this, "Successfully created", Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
    //                        Toast.makeText(MainActivity.this, "Persmission Denied", Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
                            permissionToken.continuePermissionRequest();
                        }
                    })
                    .check();
        }
        public ArrayList<File> fetchSongs(File file){
            ArrayList<File> arrayList=new ArrayList<>();//File array
            File []files =file.listFiles();  //list all the files in files variable from external storage directory
            if(files!=null){//should work only if it is not null
                for(File f: files){//its like for i in files
                    if(!f.isHidden() && f.isDirectory()){// if the file is not hidden and present in the directory then only proceeds
                        arrayList.addAll(fetchSongs(f));  //recursive function that return the list of songs
                    }
                    else{
                        if(f.getName().endsWith(".mp3") && !f.getName().startsWith(".")){// check it its a mp3 file
                            arrayList.add(f);//adds mp3 file to array
                        }
                    }
                }
            }
            return arrayList; //return the list
        }
    }

Second Activity The main listview is in here, where i display the songs. IDs are also properly allocated


    package com.example.imusic;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.RecyclerView;
    
    import android.Manifest;
    import android.content.Intent;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.Toast;
    
    
    import java.io.File;
    import java.util.ArrayList;
    
    public class MainActivity3 extends AppCompatActivity {
        ListView listView;
        ArrayList<File> Song;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView=findViewById(R.id.listView24);
            Intent intent=getIntent();
            Bundle b=intent.getExtras();
            Toast.makeText(this, "MainActivity3", Toast.LENGTH_SHORT).show();
            Song=(ArrayList) b.getParcelableArrayList("songlist"); // Song=fetchSongs(Environment.getExternalStorageDirectory());  //gets external storage directory and passes it to the function which then return list of al songs
            String []items=new String[Song.size()];//create string arr of size Song
            for(int i=0;i<Song.size();i++){
                items[i]=Song.get(i).getName().replace(".mp3","");// put the names of song in array and replaces .mp3 with " "
            }
            String[] itemss=intent.getStringArrayExtra("stringlist");
            int j=0;
            while(j<items.length){
                Log.d("String",items[j]);
                j++;
            }
            CustomAdapter adapter=new CustomAdapter(this,R.layout.mylayout,itemss);
            listView.setAdapter(adapter);
        }
    }

This is my CustomAdapter Class

Here I took the input as String array and then overrided the 2 methods getItem() and getView()
The ID of the textView in custom resource file is textView2


    package com.example.imusic;
    
    import android.content.Context;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.recyclerview.widget.RecyclerView;
    
    public class CustomAdapter extends ArrayAdapter {
    String [] arr;
    
        public CustomAdapter(@NonNull Context context, int resource, @NonNull String[] objects) {
            super(context, resource, objects);
            int j=0;
    
            this.arr=objects;
            while(j<arr.length){
                Log.d("items",arr[j]);
                j++;
            }
        }
    
        @Nullable
        @Override
        public String getItem(int position) {
            return arr[position];
        }
    
        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            convertView=LayoutInflater.from(getContext()).inflate(R.layout.mylayout,parent,false);
            TextView t=convertView.findViewById(R.id.textView2);
            t.setText(getItem(position));
            Log.d("items","hello");
            return convertView;
        }
    }

Here is the Logcat

1 Answers

I think you will be add adapter.notifydatasetchanged after the line when you are define the adapter.

Related