NullPointerException: Getting data from Database ((java.lang.String)' on a null object reference)

Viewed 139

I've created a database to store ExoPlayer's seek time so when the user tries to play the same content, if it is in the database, then it will ask the user to resume or start again but getting NullPointerException.

Here's the Database:


public class DatabaseHelper extends SQLiteOpenHelper {

   private static final int DATABASE_VERSION = 1;
   private static final String DATABASE_NAME = "mydata.db";

   private static final String EPISODE_TABLE_NAME = "episode_data";

   public DatabaseHelper(Context context) {
       super(context, DATABASE_NAME, null, DATABASE_VERSION);
   }

   @Override
   public void onCreate(SQLiteDatabase db) {
       db.execSQL(CREATE_EPISODE_DATA_TABLE());
   }

   
   private String CREATE_EPISODE_DATA_TABLE() {
       return "CREATE TABLE IF NOT EXISTS episode_data (id TEXT,timestamp TEXT)";
   }

   @Override
   public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
       db.execSQL("DROP TABLE IF EXISTS episode_data");
       onCreate(db);
   }

   public String getEpisodeData(String string2) {
       SQLiteDatabase sQLiteDatabase = this.getReadableDatabase();
       StringBuilder stringBuilder = new StringBuilder();
       stringBuilder.append("SELECT * FROM episode_data WHERE id= ");
       stringBuilder.append(string2);
       Cursor cursor = sQLiteDatabase.rawQuery(stringBuilder.toString(), null);
       String string3 = null;
       if (cursor != null) {
           boolean bl = cursor.moveToLast();
           string3 = null;
           if (bl) {
               string3 = cursor.getString(cursor.getColumnIndex("timestamp"));
           }
           cursor.close();
       }
       return string3;
   }

   public long insertEpisodeData(String string2, String string3) {
       SQLiteDatabase sQLiteDatabase = this.getWritableDatabase();
       ContentValues contentValues = new ContentValues();
       contentValues.put("id", string2);
       contentValues.put("timestamp", string3);
       long l = sQLiteDatabase.replace(EPISODE_TABLE_NAME, null, contentValues);
       sQLiteDatabase.close();
       return l;
   }

}

The activity where it stores the data from and also crashes:

public class ShowsDetailsActivity extends AppCompatActivity {

    public String episodeid;
    DatabaseHelper databaseHelper;

    @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_series_details);

       databaseHelper = new DatabaseHelper(this);

        // My rest of the code
   }

   public void iniMoviePlayerForEpisode(EpiModel epiModel,Context context){

       ShowsDetailsActivity.epiModel =epiModel;
       String type=epiModel.getServerType();
       
  if (type.equals("embed") || type.equals("vimeo") || type.equals("gdrive")){
           isVideo=false;
           initWeb(epiModel.getStreamURL());
       }else {
           isVideo=true;
           initVideoPlayer(epiModel.getStreamURL(),context,type);
       }

       }
   }

   public void setMediaUrlForTvSeries(String url, String season, String episod, String episode_id) {
       mediaUrl = url;
       this.season = season;
       this.episod = episod;
       this.episodeid = episode_id;
   }


   public void initVideoPlayer(String url, Context context, String type) {
       progressBar.setVisibility(VISIBLE);

       if (player != null) {
           player.release();
       }

       BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
       TrackSelection.Factory videoTrackSelectionFactory = new
               AdaptiveTrackSelection.Factory(bandwidthMeter);


       TrackSelector trackSelector = new
               DefaultTrackSelector(videoTrackSelectionFactory);

       player = ExoPlayerFactory.newSimpleInstance(context, trackSelector);

       simpleExoPlayerView.setPlayer(player);
       player.prepare(mediaSource, true, false);

       player.addListener(new Player.DefaultEventListener() {

           @Override
           public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

               if (playWhenReady && playbackState == Player.STATE_READY) {

                   isPlaying = true;
                   progressBar.setVisibility(View.GONE);

               } else if (playbackState == Player.STATE_READY) {

                   progressBar.setVisibility(View.GONE);
                   isPlaying = false;

                   if (player != null) {
                       StringBuilder stringBuilder = new StringBuilder();
                       stringBuilder.append("episode id: ");
                       stringBuilder.append(episodeid);
                       stringBuilder.append(" TimeStamp: ");
                       stringBuilder.append(player.getCurrentPosition() / 1000L);
                       databaseHelper.insertEpisodeData(episodeid, String.valueOf((long)player.getCurrentPosition()));
                   }

               } else if (playbackState == Player.STATE_BUFFERING) {
                   isPlaying = false;
                   progressBar.setVisibility(VISIBLE);

               } else {
                   isPlaying = false;

                   if (player != null) {
                       StringBuilder stringBuilder = new StringBuilder();
                       stringBuilder.append("episode id: ");
                       stringBuilder.append(episodeid);
                       stringBuilder.append(" TimeStamp: ");
                       stringBuilder.append(player.getCurrentPosition() / 1000L);
                       databaseHelper.insertEpisodeData(episodeid, String.valueOf((long)player.getCurrentPosition()));
                   }
               }

           }
       });

       String getPlayed = databaseHelper.getEpisodeData(episodeid);
       if (getPlayed != null) {
           showResumeAlert();
           return;
       }
       player.setPlayWhenReady(true);

   }

   private void showResumeAlert () {
       new AlertDialog.Builder(this)
               .setTitle("Do you want to resume from where you left ?")
               .setPositiveButton("Resume", new DialogInterface.OnClickListener() {
                   @Override
                   public void onClick(DialogInterface dialog, int which) {

                       String getPlayed = databaseHelper.getEpisodeData(episodeid);
                       if (getPlayed != null) {
                           player.seekTo(Long.parseLong(getPlayed));
                           player.setPlayWhenReady(true);
                       }
                   }
               })
               .setNegativeButton("Start Again", new DialogInterface.OnClickListener() {
                   @Override
                   public void onClick(DialogInterface dialog, int which) {
                       player.setPlayWhenReady(true);
                   }
               })
               .setCancelable(false)
               .show();
   }

    // My rest of the code

}

The adapter:

public class DirectorApater extends RecyclerView.Adapter<DirectorApater.OriginalViewHolder> {

   private List<EpiModel> items;
   private Context ctx;

   int selectedPosition=-1;
   private int seasonNo;


   public DirectorApater(Context context, List<EpiModel> items,String name, int seasonNo) {
       ArrayList<EpiModel> arrayList=new ArrayList<>();
       for(int i=0;i<items.size();i++){
           if(items.get(i).getSeson().equals(name)){
               arrayList.add(items.get(i));
           }
       }

       items.clear();
       this.items = arrayList;
       this.seasonNo = seasonNo;

       ctx = context;
   }


   @Override
   public DirectorApater.OriginalViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
       DirectorApater.OriginalViewHolder vh;
       View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_director_name, parent, false);
       vh = new DirectorApater.OriginalViewHolder(v);
       return vh;
   }

   @Override
   public void onBindViewHolder(final DirectorApater.OriginalViewHolder holder, final int position) {
       final EpiModel obj = items.get(position);

       holder.llEpi.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               selectedPosition=position;
               notifyDataSetChanged();
               ((ShowsDetailsActivity)ctx).setMediaUrlForTvSeries(obj.getStreamURL(), obj.getSeson(), obj.getEpi(), obj.getEpisode_id());

 if (!castSession) {
                   new ShowsDetailsActivity().iniMoviePlayerForEpisode(obj,ctx);
               } else {
                   ((ShowsDetailsActivity)ctx).showQueuePopup(ctx, holder.llEpi, ((ShowsDetailsActivity)ctx).getMediaInfo());

               }
           }
       });

   }
   
   @Override
   public int getItemCount() {
       return items.size();
   }

   public class OriginalViewHolder extends RecyclerView.ViewHolder {

       // some code

       public OriginalViewHolder(View v) {
           super(v);
            // some code
       }
   }

So basically when a user clicks on the recyclerview item, it passes the data to the activity class "(ShowsDetailsActivity)ctx).setMediaUrlForTvSeries(obj.getStreamURL(), obj.getSeson(), obj.getEpi(), obj.getEpisode_id());"

App works fine without

 String getPlayed = databaseHelper.getEpisodeData(episodeid);
        if (getPlayed != null) {
            showResumeAlert();
            return;
        }

in ShowsDetailsActivity class but crashes with this error log when I add it:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.myapp.db.DatabaseHelper.getEpisodeData(java.lang.String)' on a null object reference

1 Answers

You are calling the iniMoviePlayerForEpisode method here:

new ShowsDetailsActivity().iniMoviePlayerForEpisode(obj,ctx);

but at that point onCreate was not yet called and thus your databaseHelper is still null. Check the reference i linked: onCreate is called when your Activity starts, not when the object is created.

Related