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

huangapple go评论76阅读模式
英文:

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

问题

我已经为您翻译了您提供的内容,请查阅:

我已经创建了一个数据库来存储ExoPlayer的播放进度,所以当用户尝试播放相同的内容时,如果在数据库中存在该内容,它会要求用户恢复播放或重新开始,但是会出现NullPointerException错误。

这是数据库部分:

public class DatabaseHelper extends SQLiteOpenHelper {

    // ... (其余代码)

    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 class ShowsDetailsActivity extends AppCompatActivity {

    // ... (其余代码)

    private void showResumeAlert() {
        new AlertDialog.Builder(this)
                .setTitle("您想要从上次离开的地方继续播放吗?")
                .setPositiveButton("继续", 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("重新开始", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        player.setPlayWhenReady(true);
                    }
                })
                .setCancelable(false)
                .show();
    }

    // ... (其余代码)
}

适配器部分:

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

    // ... (其余代码)

    @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());

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

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

        // ... (其余代码)
    }

    // ... (其余代码)
}

希望这些翻译对您有所帮助。如果您有任何疑问,请随时问我。

英文:

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 = &quot;mydata.db&quot;;

   private static final String EPISODE_TABLE_NAME = &quot;episode_data&quot;;

   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 &quot;CREATE TABLE IF NOT EXISTS episode_data (id TEXT,timestamp TEXT)&quot;;
   }

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

   public String getEpisodeData(String string2) {
       SQLiteDatabase sQLiteDatabase = this.getReadableDatabase();
       StringBuilder stringBuilder = new StringBuilder();
       stringBuilder.append(&quot;SELECT * FROM episode_data WHERE id= &quot;);
       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(&quot;timestamp&quot;));
           }
           cursor.close();
       }
       return string3;
   }

   public long insertEpisodeData(String string2, String string3) {
       SQLiteDatabase sQLiteDatabase = this.getWritableDatabase();
       ContentValues contentValues = new ContentValues();
       contentValues.put(&quot;id&quot;, string2);
       contentValues.put(&quot;timestamp&quot;, 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(&quot;embed&quot;) || type.equals(&quot;vimeo&quot;) || type.equals(&quot;gdrive&quot;)){
           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 &amp;&amp; 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(&quot;episode id: &quot;);
                       stringBuilder.append(episodeid);
                       stringBuilder.append(&quot; TimeStamp: &quot;);
                       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(&quot;episode id: &quot;);
                       stringBuilder.append(episodeid);
                       stringBuilder.append(&quot; TimeStamp: &quot;);
                       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(&quot;Do you want to resume from where you left ?&quot;)
               .setPositiveButton(&quot;Resume&quot;, 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(&quot;Start Again&quot;, 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&lt;DirectorApater.OriginalViewHolder&gt; {

   private List&lt;EpiModel&gt; items;
   private Context ctx;

   int selectedPosition=-1;
   private int seasonNo;


   public DirectorApater(Context context, List&lt;EpiModel&gt; items,String name, int seasonNo) {
       ArrayList&lt;EpiModel&gt; arrayList=new ArrayList&lt;&gt;();
       for(int i=0;i&lt;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

得分: 4

你在这里调用了 iniMoviePlayerForEpisode 方法:

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

但是在那个时候,onCreate 方法还没有被调用,因此你的 databaseHelper 仍然为 null。请查阅我提供的链接,其中说明了 onCreate 方法是在 Activity 启动时调用的,而不是在对象创建时调用。

英文:

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.

huangapple
  • 本文由 发表于 2020年8月29日 04:57:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/63640791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定