NullPointerException:从数据库获取数据((java.lang.String)';在空对象引用上)
我创建了一个数据库来存储ExoPlayer的搜索时间,因此当用户尝试播放相同的内容时,如果它在数据库中,那么它将要求用户继续或重新启动,但会得到NullPointerException 以下是数据库:NullPointerException:从数据库获取数据((java.lang.String)';在空对象引用上),java,android,Java,Android,我创建了一个数据库来存储ExoPlayer的搜索时间,因此当用户尝试播放相同的内容时,如果它在数据库中,那么它将要求用户继续或重新启动,但会得到NullPointerException 以下是数据库: public class DatabaseHelper extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 1; private static final String DATABASE_NA
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;
}
}
存储来自的数据的活动,也会崩溃:
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
}
适配器:
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
}
}
在ShowsDetailsActivity类中,但在添加此错误日志时崩溃:
java.lang.NullPointerException:尝试调用虚拟方法
'java.lang.String
null对象引用上的com.myapp.db.DatabaseHelper.geteposodedata(java.lang.String)”
您正在此处调用
iniMoviePlayerForEpisode
方法:
new ShowsDetailsActivity().iniMoviePlayerForEpisode(obj,ctx);
但此时尚未调用,因此您的
databaseHelper
仍然为空。检查我链接的引用:onCreate
是在活动开始时调用的,而不是在对象创建时调用的。您在哪里调用iniMoviePlayerForEpisode
?@puelo,因为API以两种格式发送视频,一种是web(嵌入),在webview中加载,另一个是在ExoPlayer中播放的普通视频。@puelo检查我的编辑,我添加了这个方法。为了避免字符限制,我不得不删除。我仍然看不到在movieplayerForepisode中调用的位置。您只添加了完整的正文。@puelo抱歉,请检查我的编辑,我正在从适配器调用它。我刚刚尝试过,但由于相同的错误而崩溃。databaseHelper还保存了工作正常的内容详细信息,因此它不是空的。我唯一的问题是关于eposodeid字符串。@puelo看起来是正确的。我没有看到使用当前状态obj和上下文obj调用onCreate的任何地方。因此,您仍然有一个空的databaseHelper对象。@StevenRõgrê如果您的意思是insertEpisodeData
,那么这是有效的,因为它只在侦听器的回调中调用,而不是直接在iniMoviePlayerForEpisode
方法中调用。当活动已经启动时,可能会调用回调。@puelo好的,那么您建议我在这里做什么?我已经想了好几个小时了,但我还没想清楚。我对安卓系统不太在行,但你可以试着让你的databaseHelper成为一个单件,就像这里提到的:然后自由访问它。其他建议:将databaseHelper实例的创建移到构造函数中,而不是onCreate
new ShowsDetailsActivity().iniMoviePlayerForEpisode(obj,ctx);