腾讯轻听模仿流水账(4):16.12.2
今天博主去做了一个脸部的小手术·····啊,脸好疼,现在还疼着呢···
言归正传,开始今天的项目记录
1、今天写代码的时候发现一个问题,点击列表上的音乐,多次点击之后就会出现异常,APP停止工作,异常代码如下:
FATAL EXCEPTION: main
Process: com.example.mic54496.wellmusic, PID: 21756
java.lang.IllegalStateException
at android.media.MediaPlayer._prepare(Native Method)
at android.media.MediaPlayer.prepare(MediaPlayer.java:1154)
at Interactor.SongPlayerInteractor.playMusicInList(SongPlayerInteractor.java:52)
at Presenter.impl.SongPresenterImpl.playSong(SongPresenterImpl.java:62)
at com.example.mic54496.wellmusic.Ui.Fragmnet.SongFrag$1$2.onItemClick(SongFrag.java:110)
at android.widget.AdapterView.performItemClick(AdapterView.java:305)
at android.widget.AbsListView.performItemClick(AbsListView.java:1172)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3185)
at android.widget.AbsListView$4.run(AbsListView.java:4003)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5294)
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:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:134)
我的代码是:
//通过点击列表来播放音乐
public void playMusicInList(String fileName)
{
try
{
if (mediaPlayer.isPlaying()||curSong!=null)
mediaPlayer.reset();
mediaPlayer.setDataSource(fileName);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException e)
{
Toast.makeText(mContext, "error:" + e.toString(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
问题出在mediaPlayer.prepare();
这里,去网上找了资料,有这么几个网址:
http://lovelease.iteye.com/blog/2105616
http://stackoverflow.com/questions/15730772/android-java-lang-illegalstateexception-mediaplayer-isplaying/15730932
主要意思就是mediaPlayer在release之后需要重新初始化回到idie状态····
但是我自始至终都没有用到release这个方法啊····
但是我发现主要是mediaPlayer.prepare();
这行代码有IllegalStateException异常抛出,但是因为没有处理,所以APP就直接GG了,所以现在,哼哼,给它加个异常处理APP就不会GG了
mediaPlayer.setDataSource(fileName);
try
{
mediaPlayer.prepare();
}catch (IllegalStateException e)
{
Log.d("player error",e.toString());
}
mediaPlayer.start();
就像这样···你可以发现其实根本没有处理这个异常,但是我这么做了之后,随意点击列表上的歌曲,APP都不会强退,后续的操作也都没有异常,所以这个问题就这么过去了···
不知道这个问题到底是怎么回事产生的,以后再说···
2、现在开始把从contentProvider中获得的Arraylist<Song>保存起来,这里准备使用greenDao这个ORM框架,相关介绍文章:http://blog.csdn.net/u012702547/article/details/52226163
现在改变策略,准备把单个的Song存入本地数据库,然后打开APP的时候判断本地数据库是否要更新,不更新的话直接从greenDao中取就可以了,一开始有点不想这么做,觉得性能太差,但是,不试试怎么知道呢?试试吧,开始!
按照上面的链接把本地数据库搭建完,然后理一下音乐获取的思路:
如果是时候次打开APP,那么就直接从contentProvider中获取数据,该数据保存在本地类一份,保存在数据库一份
下次打开APP,从本地数据库获取数据,不管contentProvider
3、定好上面的规矩之后,发现了之前做项目一直存在的问题,就是使用viewPager来做顶部的导航栏,第一个页面的数据加载完毕之后,移到第二个页,再回到第一个页,数据不会重新加载,但是如果从第二个页再滑到第三个页,再回到第一个页,第一个页的数据就会被重新加载,这个问题怎么解决呢?
这个博客里就有解决方法:http://blog.csdn.net/icyfox_bupt/article/details/18356461
很简单,只要让ViewPager多缓存一页就好了·····
pager.setOffscreenPageLimit(2);
4、现在照第二条使用GreenDao,但是发现
public SongDBInteractor(Context context){
helper=new DaoMaster.DevOpenHelper(context,"song.db",null);
daoMaster=new DaoMaster(helper.getWritableDb());
daoSession=daoMaster.newSession();
songDao=daoSession.getSongDao();
}
这个的创建过程特别卡,这个创建过程大概有10到15秒,简直不能忍!
现在发现问题出在哪里了,原来
helper=new DaoMaster.DevOpenHelper(context,"song.db",null);
daoMaster=new DaoMaster(helper.getWritableDb());
daoSession=daoMaster.newSession();
这些变量的创建必须在MyApplication中(就是我们自己定义的类继承Application)!下面附上代码:
public class MyApplication extends Application
{
private DaoMaster.DevOpenHelper mHelper;
private SQLiteDatabase db;
private DaoMaster mDaoMaster;
private DaoSession mDaoSession;
public static MyApplication instances;
private static Context context;
@Override
public void onCreate() {
super.onCreate();
instances = this;
context=getApplicationContext();
setDatabase();
}
public static MyApplication getInstances(){
return instances;
}
public static Context getContext(){
return context;
}
/**
* 设置greenDao
*/
private void setDatabase() {
// 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
// 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
// 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
// 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
mHelper = new DaoMaster.DevOpenHelper(this, "song-db", null);
db = mHelper.getWritableDatabase();
// 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
mDaoMaster = new DaoMaster(db);
mDaoSession = mDaoMaster.newSession();
}
public DaoSession getDaoSession() {
return mDaoSession;
}
public SQLiteDatabase getDb() {
return db;
}
}
但是现在发现把音乐持久化的时间比我想象的要久,而且发现这个greenORM insert一个Song歌曲对象的时间实在是太长了,不知道到底是哪里出了问题,现在决定使用sugarORM看看效果
5、上述决定用sugarORM代替greenORM,看最后效果好不好,因为我这里本来是使用tortotiseGit来进行版本管理的,现在需要开一个新分支,如果这个新分支运行良好,那么就把这个新分支作为主分支,这个又该怎么做呢?等什么时候有空再写。
6、现在发现如何将扫描到的音乐加入本地存储,并且后续的一些细节也没有想清楚,现在决定先暂停一下这个项目的进度,先去学习一下别人的项目,等找到相关项目也会在这里分享自己的看法。