尝试提交查询时 Android TV SearchFragment 崩溃(NPE)

Posted

技术标签:

【中文标题】尝试提交查询时 Android TV SearchFragment 崩溃(NPE)【英文标题】:Android TV SearchFragment crash when trying to submit query(NPE) 【发布时间】:2015-04-10 14:35:28 【问题描述】:

我正在尝试在我的电视应用中实现搜索,但是当我在搜索时按下提交按钮时,它会崩溃并显示以下消息:

 java.lang.NullPointerException: Attempt to invoke virtual method 'int android.support.v17.leanback.widget.ObjectAdapter.size()' on a null object reference
            at android.support.v17.leanback.app.SearchFragment.focusOnResults(SearchFragment.java:581)
            at android.support.v17.leanback.app.SearchFragment.queryComplete(SearchFragment.java:567)
            at android.support.v17.leanback.app.SearchFragment.access$1300(SearchFragment.java:63)
            at android.support.v17.leanback.app.SearchFragment$4.onKeyboardDismiss(SearchFragment.java:257)
            at android.support.v17.leanback.widget.SearchBar$6$2.run(SearchBar.java:257)
            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:5221)
            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:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

下面是我对SearchFragment 的实现:

public class SearchTVFragment extends SearchFragment implements SearchFragment.SearchResultProvider

    private static final int SEARCH_DELAY_MS = 300;
    private static final String TAG = SearchTVFragment.class.getSimpleName();

    final private ArrayObjectAdapter mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
    final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
    ScheduledFuture<List<VideoEntryWrapper>> searchResult;

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        setSpeechRecognitionCallback(new SpeechRecognitionCallback() 
            @Override
            public void recognizeSpeech() 

            
        );

        setSearchResultProvider(this);
        Toast.makeText(getActivity(),"Search onCreate", Toast.LENGTH_SHORT).show();

    

    @Override
    public ArrayObjectAdapter getResultsAdapter() 
        return mRowsAdapter;
    

    @Override
    public boolean onQueryTextChange(String newQuery) 
        return false;
    

    @Override
    public boolean onQueryTextSubmit(String query) 
        return processQuery(query);
    

    boolean processQuery(String query)
        Log.debug(TAG,"processQuery : "+query);
        if(searchResult != null)
            searchResult.cancel(true);
        
        searchResult = scheduledExecutorService.schedule(new SearchVideoTask(query, 0, 20)
                , SEARCH_DELAY_MS, TimeUnit.MILLISECONDS);
        processResponse(searchResult);
        return true;
    

    private void processResponse(final ScheduledFuture<List<VideoEntryWrapper>> searchRes)
        new AsyncTask<Void,Void,List<VideoEntryWrapper>>()
            @Override
            protected List<VideoEntryWrapper> doInBackground(Void... params) 
                try 
                    Log.debug(TAG,">> processResponse");
                    List<VideoEntryWrapper> videoEntryWrappers = searchRes.get();
                    Log.debug(TAG,"<< processResponse");
                    return videoEntryWrappers;
                 catch (CancellationException|InterruptedException e) 
                    Log.debug(TAG,"<< processResponse cancelled");
                 catch (ExecutionException e) 
                    Log.error(TAG,"<< processResponse error : "+e.getMessage());
                
                return null;
            

            @Override
            protected void onPostExecute(List<VideoEntryWrapper> videoEntryWrappers) 
                if(videoEntryWrappers != null)
                    Log.debug(TAG,">> view response");

                    ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new SongEntryPresenter());

                    for (VideoEntryWrapper videoEntryWrapper: videoEntryWrappers)
                        listRowAdapter.add(videoEntryWrapper);
                    

                    mRowsAdapter.add(new ListRow(listRowAdapter));

                    Log.debug(TAG,"<< view response");

                 else 
                    Log.debug(TAG,">> no data to view response");
                
            
        .execute();
    


这里有什么问题?如果我在getResultsAdapter() 方法中提供适配器,为什么适配器是null

日志转储:

3    1660-1671/com.mypackage.name I/art﹕ WaitForGcToComplete blocked for 3.066s for cause HeapTrim
02-10 16:59:23.428    1660-1660/com.mypackage.name D/InputEventConsistencyVerifier﹕ TouchEvent: Source was not SOURCE_CLASS_POINTER.
    in android.support.v17.leanback.widget.SearchEditText3b6b36a3 VFED..CL .F.P.... 32,18-799,57 #7f0e0192 app:id/lb_search_text_editor
    0: sent at 952267000000, MotionEvent  action=ACTION_DOWN, id[0]=0, x[0]=767.0, y[0]=39.0, toolType[0]=TOOL_TYPE_UNKNOWN, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=952267, downTime=952267, deviceId=0, source=0x0 
    -- recent events --
    1: sent at 952082381000, MotionEvent  action=ACTION_UP, id[0]=0, x[0]=125.0, y[0]=18.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=952082, downTime=951974, deviceId=0, source=0x1002 
    2: sent at 951974040000, MotionEvent  action=ACTION_DOWN, id[0]=0, x[0]=125.0, y[0]=18.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=951974, downTime=951974, deviceId=0, source=0x1002 
02-10 16:59:23.431    1660-1660/com.mypackage.name D/InputEventConsistencyVerifier﹕ TouchEvent: Source was not SOURCE_CLASS_POINTER.
    in android.support.v17.leanback.widget.SearchEditText3b6b36a3 VFED..CL .F.P.... 32,18-799,57 #7f0e0192 app:id/lb_search_text_editor
    0: sent at 952465000000, MotionEvent  action=ACTION_UP, id[0]=0, x[0]=767.0, y[0]=39.0, toolType[0]=TOOL_TYPE_UNKNOWN, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=952465, downTime=952465, deviceId=0, source=0x0 
    -- recent events --
    1: sent at 952267000000, MotionEvent  action=ACTION_DOWN, id[0]=0, x[0]=767.0, y[0]=39.0, toolType[0]=TOOL_TYPE_UNKNOWN, buttonState=0, metaState=0, flags=0x80000000, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=952267, downTime=952267, deviceId=0, source=0x0 
    2: sent at 952082381000, MotionEvent  action=ACTION_UP, id[0]=0, x[0]=125.0, y[0]=18.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=952082, downTime=951974, deviceId=0, source=0x1002 
    3: sent at 951974040000, MotionEvent  action=ACTION_DOWN, id[0]=0, x[0]=125.0, y[0]=18.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=951974, downTime=951974, deviceId=0, source=0x1002 
02-10 16:59:23.905    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 26600(1800KB) AllocSpace objects, 54(1086KB) LOS objects, 13% free, 12MB/14MB, paused 2.427ms total 1.699s
02-10 16:59:24.101    1660-1660/com.mypackage.name E/RecyclerView﹕ No adapter attached; skipping layout
02-10 16:59:25.639    1660-1672/com.mypackage.name I/art﹕ Background partial concurrent mark sweep GC freed 25993(1512KB) AllocSpace objects, 63(1464KB) LOS objects, 25% free, 11MB/15MB, paused 3.207ms total 340.306ms
02-10 16:59:28.745    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 5324(417KB) AllocSpace objects, 13(240KB) LOS objects, 1% free, 15MB/15MB, paused 2.204ms total 229.996ms
02-10 16:59:29.129    1660-1672/com.mypackage.name I/art﹕ Background partial concurrent mark sweep GC freed 11273(526KB) AllocSpace objects, 24(606KB) LOS objects, 21% free, 14MB/18MB, paused 9.062ms total 355.074ms
02-10 16:59:29.132    1660-1671/com.mypackage.name I/art﹕ WaitForGcToComplete blocked for 226.367ms for cause HeapTrim
02-10 16:59:31.354    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 15296(1193KB) AllocSpace objects, 48(1120KB) LOS objects, 10% free, 16MB/18MB, paused 3.980ms total 118.393ms
02-10 16:59:32.953    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 2874(255KB) AllocSpace objects, 14(363KB) LOS objects, 3% free, 17MB/18MB, paused 12.077ms total 66.367ms
02-10 16:59:34.865    1660-1672/com.mypackage.name I/art﹕ Background partial concurrent mark sweep GC freed 16826(947KB) AllocSpace objects, 44(1077KB) LOS objects, 18% free, 17MB/21MB, paused 1.929ms total 678.420ms
02-10 16:59:36.906    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 12683(1028KB) AllocSpace objects, 45(1056KB) LOS objects, 9% free, 19MB/21MB, paused 2.011ms total 168.397ms
02-10 16:59:38.322    1660-1660/com.mypackage.name E/RecyclerView﹕ No adapter attached; skipping layout
02-10 16:59:38.539    1660-1660/com.mypackage.name D/AndroidRuntime﹕ Shutting down VM
02-10 16:59:38.919    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 4319(368KB) AllocSpace objects, 8(144KB) LOS objects, 1% free, 20MB/21MB, paused 2.288ms total 249.723ms
02-10 16:59:39.101    1660-1672/com.mypackage.name I/art﹕ Background partial concurrent mark sweep GC freed 12459(582KB) AllocSpace objects, 36(956KB) LOS objects, 17% free, 19MB/23MB, paused 2.706ms total 173.491ms
02-10 16:59:40.871    1660-1672/com.mypackage.name I/art﹕ Background sticky concurrent mark sweep GC freed 26845(1677KB) AllocSpace objects, 36(837KB) LOS objects, 8% free, 20MB/22MB, paused 2.210ms total 128.916ms
02-10 16:59:41.121    1660-1660/com.mypackage.name E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.mypackage.name, PID: 1660
    java.lang.NullPointerException: Attempt to invoke virtual method 'int android.support.v17.leanback.widget.ObjectAdapter.size()' on a null object reference
            at android.support.v17.leanback.app.SearchFragment.focusOnResults(SearchFragment.java:581)
            at android.support.v17.leanback.app.SearchFragment.queryComplete(SearchFragment.java:567)
            at android.support.v17.leanback.app.SearchFragment.access$1300(SearchFragment.java:63)
            at android.support.v17.leanback.app.SearchFragment$4.onKeyboardDismiss(SearchFragment.java:257)
            at android.support.v17.leanback.widget.SearchBar$6$2.run(SearchBar.java:257)
            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:5221)
            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:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
02-10 16:59:43.968    1660-1660/com.mypackage.name I/Process﹕ Sending signal. PID: 1660 SIG: 9
02-10 16:59:45.723    1798-1798/com.mypackage.name I/MultiDex﹕ VM with version 2.1.0 has multidex support
02-10 16:59:45.724    1798-1798/com.mypackage.name I/MultiDex﹕ install
02-10 16:59:45.724    1798-1798/com.mypackage.name I/MultiDex﹕ VM has multidex support, MultiDex support library is disabled.
02-10 16:59:46.337    1798-1798/com.mypackage.name I/MyAppApplication﹕ >> onCreate
02-10 16:59:46.349    1798-1798/com.mypackage.name D/DeviceUtils﹕ >> getAdvertisingId
02-10 16:59:46.354    1798-1798/com.mypackage.name D/DeviceUtils﹕ << getAdvertisingId
02-10 16:59:46.377    1798-1814/com.mypackage.name D/DeviceUtils﹕ >> getAdvertisingId try fetching id
02-10 16:59:46.381    1798-1814/com.mypackage.name D/DeviceUtils﹕ >> getAdvertisingId inSyncBlock id not exist
02-10 16:59:46.396    1798-1814/com.mypackage.name D/DeviceUtils﹕ >> getAdId
02-10 16:59:46.471    1798-1798/com.mypackage.name I/Crashlytics﹕ Initializing Crashlytics 1.1.13.29
02-10 16:59:47.100    1798-1798/com.mypackage.name I/MyAppApplication﹕ << onCreate
02-10 16:59:52.300    1798-1798/com.mypackage.name D/InstallationTableWrapper﹕ Save installation successful

【问题讨论】:

你检查过回复的内容了吗?您在 onPostExecute() 方法中向 mRowsFragment 添加了多少元素? @dextor,它甚至没有到达那个代码,只是在我得到 onQueryTextSubmit 回调之前崩溃 那么让我直说吧。您的代码到达的最后一个已知点在哪里?你能发布你的日志转储吗? 我也会强烈引用您的 AsyncTask 而不是留下它。 @dextor,谢谢,请检查更新的问题,我附上了更多日志,有有趣的行-1660/com.mypackage.name E/RecyclerView﹕ No adapter attached; skipping layout 【参考方案1】:

我也在寻找答案。解决方案很简单。你和我忘记告诉 Class 将这个类设置为默认搜索响应。

添加:

setSearchResultProvider(this);

在 onCreate 中修复此问题。就是这样。

【讨论】:

以上是关于尝试提交查询时 Android TV SearchFragment 崩溃(NPE)的主要内容,如果未能解决你的问题,请参考以下文章

Android TV 开发

如何从 Android TV 应用程序中删除垂直信箱?

Android TV:如何使用 Leanbak 自定义 android TV 的左侧导航面板?

无法在 android TV Preferences 片段中找到提供者

Android-TV 应用显示白屏

React Native Android TV 控件