在service中使用ContentResolver报错

问题描述

在service中使用ContentResolver报错,报错如下,请问如何解决?

报错

FATAL EXCEPTION: main
Process: com.mp.mmedicaplayer, PID: 16990
  java.lang.RuntimeException: Unable to instantiate service com.mp.mmedicaplayer.service.MusicService: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ContentResolver android.content.Context.getContentResolver()' on a null object reference
  at android.app.ActivityThread.handleCreateService(ActivityThread.java:3390)
  at android.app.ActivityThread.-wrap5(ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1753)
  at android.os.Handler.dispatchMessage(Handler.java:102)
  at android.os.Looper.loop(Looper.java:159)
  at android.app.ActivityThread.main(ActivityThread.java:6385)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1096)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:883)
   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ContentResolver android.content.Context.getContentResolver()' on a null object reference
  at com.mp.mmedicaplayer.service.MusicService.getMusicToArray(MusicService.java:211)
  at com.mp.mmedicaplayer.service.MusicService.<init>(MusicService.java:48)
  at java.lang.Class.newInstance(Native Method)
  at android.app.ActivityThread.handleCreateService(ActivityThread.java:3387)
  at android.app.ActivityThread.-wrap5(ActivityThread.java) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1753) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  at android.os.Looper.loop(Looper.java:159) 
  at android.app.ActivityThread.main(ActivityThread.java:6385) 
  at java.lang.reflect.Method.invoke(Native Method) 

代码

public void getMusicToArray(){
        /**
         * 此处目前存在报错
         *
         */
        ContentResolver contentResolver = getContentResolver();
        Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        List<MusicListData> mListData = new ArrayList<>();
        //Cursor是每行的集合
        if(cursor.moveToFirst()){
            for(int i = 0; i <cursor.getCount();i++) {
                MusicListData data = new MusicListData();
                long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID));
                String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
                String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
                long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));
                String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                String abum = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
                long albulm_id = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
                int ismusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));
                Log.d("MMMM",url);

                if (ismusic != 0 && duration / (500 * 60) >= 1) {
                    Log.d("M","循环2");

                    musicPath[i] = url;

                    data.setTitle(title);
                    data.setUrl(url);
                    data.setSonger(artist);
                    mListData.add(data);
                }
                //往下移动一行
                cursor.moveToNext();
            }

        }
        //释放集合
        cursor.close();
    }
阅读 5.6k
2 个回答
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ContentResolver android.content.Context.getContentResolver()' on a null object reference
at com.mp.mmedicaplayer.service.MusicService.getMusicToArray(MusicService.java:211)
at com.mp.mmedicaplayer.service.MusicService.<init>(MusicService.java:48)

通过上面的报错信息可以看到getMusicToArray()是在Service的构造函数中调用的,引起报错的调用是Service#getContentResolver()。看看Android源码:

public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
    ... ...
}

public class ContextWrapper extends Context {
    Context mBase;

    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

    @Override
    public ContentResolver getContentResolver() {
        return mBase.getContentResolver();
    }
}

Service#getContentResolver()最终调用的是mBase.getContentResolver(),而mBase赋值的方法attachBaseContext(Context)是由系统按照生命周期来操作的,也自然不会先于构造函数。在构造函数中调用Context相关函数也自然会报错。

getContentResolver()需要context,试试getApplicationContext().getContentResolver()

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题