2

I'm trying to implement search in my TV app, but when I press submit button on search it crashes with the following message :

 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)

Below is my implementation of 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();
    }

}

What is wrong here ? Why adapter is null if I provide it in getResultsAdapter() method ?

dump of logs :

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.SearchEditText{3b6b36a3 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.SearchEditText{3b6b36a3 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
Mickey Tin
  • 3,408
  • 10
  • 42
  • 71
  • Have you checked the content of the response? How many elements are you adding to `mRowsFragment` in your `onPostExecute()` method? – Sebastiano Feb 10 '15 at 14:21
  • @dextor, it doesn't even reach that code, just crashes before I get `onQueryTextSubmit` callback – Mickey Tin Feb 10 '15 at 14:25
  • So let me get this straight. Where is the last known point reached by your code? Could you post a dump of your logs? – Sebastiano Feb 10 '15 at 14:40
  • I'd also keep a strong reference to your `AsyncTask` rather than leaving it be. – Sebastiano Feb 10 '15 at 14:49
  • @dextor, thanks, please check the updated question, I've attached more logs, there is interesting line `-1660/com.mypackage.name E/RecyclerView﹕ No adapter attached; skipping layout` – Mickey Tin Feb 10 '15 at 15:03
  • The `No adapter attached` message is normal, since you're providing an empty `mRowsFragment` at the beginning. However, I'm not seeing any of your apps' logs (those that have the `SearchTVFragment` tag). Does this mean that none of the debug lines you have put are being reached? Also, have you tried keeping a strong reference to the task? – Sebastiano Feb 10 '15 at 15:11
  • @dextor, looks like so. I've tried to keep the reference, but no changes. – Mickey Tin Feb 10 '15 at 15:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/70643/discussion-between-dextor-and-mickey-tin). – Sebastiano Feb 10 '15 at 15:29

1 Answers1

1

I was also searching for answer to it. Resolution was simple. You and me forgot to tell Class to set this class as default search response.

Add:

setSearchResultProvider(this);

in onCreate to get this fixed. Thats all.