【问题标题】:Android: IntentService getting Result back to ListFragmentAndroid:IntentService 将结果返回给 ListFragment
【发布时间】:2013-05-17 05:39:41
【问题描述】:

我基于这个demo构建了一个功能齐全的FragmentActivity

最初(与我应用中的其他活动一样)数据是从 UI 线程中的 SQLite 加载到 FragmentActivity.ListFragment.ListView 中的。

我已经成功地将另外两个活动(不是片段或列表活动)转换为使用 IntentService 从 SQLite 获取数据的 ResultReceiver 范例。此实例的明显区别在于,自定义 ResultReceiver 是在 ListFragment 中声明的,而不是 FragmentActivity

public EWTRReceiver ArrayListFragmentReceiver;

问题: IntentService 获取请求,提取数据但无法将数据返回到 ListFragment:NullPointerException on IntentService.rspPlayers() 中的这一行:

r.send(mSignal, resultData);

我确信我错过了一些简单的东西,这会让我觉得自己像个白痴……我只需要被推向正确的方向。

以下是 (1) ListFragmentIntenService 的调用,(2) IntentService 的 onHandleIntent 和 (3) IntentService 中回调 ListFragment 的方法 (rspPlayers())。

谢谢!

FragmentActivity.ListFragment.callCtlr():

    private void callCtlr(int mSignal){
        if (BuildConfig.DEBUG) {
            Log.i(Constants.TAG_FRGACTPLAYERS, "ArrayListFragment.callCtlr() called with signal: "+mSignal);
        }
        /** Intent to transmit between processes */
        Intent intent = new Intent(getActivity(), CtlPlayers.class);
        // declare Source of Signal
        intent.putExtra("Source", ArrayListFragmentReceiver);
        /** process signal to send to CtlPlayers */
        switch (mSignal){
           case Constants.S_DB_READPLYRLDR:
               if (BuildConfig.DEBUG) {
                   Log.i(Constants.TAG_FRGACTPLAYERS, "ArrayListFragment.callCtlr(S_DB_READPLYRLDR) to CtlPlayers.");
               }
               // Send CtlAlliances the request for the list of Alliances in current Sector
               intent.putExtra("CurrentSector", this.getArguments().getString("FSECTR"));
               intent.putExtra("CurrentAlliance", this.getArguments().getString("FANAME"));
               intent.putExtra("signal", Constants.S_DB_READPLYRLDR);
               break;
          case Constants.S_DB_READPLYRREC:
               if (BuildConfig.DEBUG) {
                   Log.i(Constants.TAG_FRGACTPLAYERS, "ArrayListFragment.callCtlr(S_DB_READPLYRREC) to CtlPlayers.");
               }
               // Send CtlAlliances the request for the list of Alliances in current Sector
               intent.putExtra("CurrentSector", this.getArguments().getString("FSECTR"));
               intent.putExtra("CurrentAlliance", this.getArguments().getString("FANAME"));
               intent.putExtra("signal", Constants.S_DB_READPLYRREC);
               break;
            default:
                //do nothing
                break;
        }
        getActivity().startService(intent);
    }

IntentService.onHandleIntent():

    protected void onHandleIntent(Intent intentREQ) {
    if (BuildConfig.DEBUG) {
        Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(Intent intent) called.");
    }
    /** get the receiver and bundle from the incoming Intent */
    ResultReceiver rInComing = intentREQ.getParcelableExtra("Source");

    /** get the bundle from the incoming Intent */
    extras = intentREQ.getExtras();
    /** variable to convey results to ActDlgAddPlyr */
    boolean mAnswer = false;
    /** tracks ActSector's context */
    Context mCtx    = getApplicationContext();
    int     mSignal = intentREQ.getIntExtra("signal", Constants.R_NO_SIGNAL);
    if (BuildConfig.DEBUG) {
        Log.i(Constants.TAG_CTLPLAYERS, "Signal Received = " + mSignal);
    }

    switch (mSignal) {
    case Constants.R_NO_SIGNAL :
        if (BuildConfig.DEBUG) {
            Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): NO READABLE SIGNAL WAS RECEIVED!");
        }
        break;
    case Constants.S_DB_ADDPLYR :
        if (BuildConfig.DEBUG) {
            Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): S_DB_ADDPLYR received.");
        }
        synchronized (this) {
            // Get the New Sector Name from the bundle
            if (BuildConfig.DEBUG) {
                Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): S_DB_ADDPLYR received with New Player.");
            }
            mAnswer = addNewPlayer(mCtx, extras);
            rspPlayers(Constants.R_DB_ADDPLYR, mAnswer, rInComing);
        }
        break;
    case Constants.S_DB_READPLYRLDR :
        if (BuildConfig.DEBUG) {
            Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): S_DB_READPLYRLDR received.");
        }
        synchronized (this) {
            // Get the New Sector Name from the bundle
            if (BuildConfig.DEBUG) {
                Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): S_DB_READPLYRLDR received.");
            }
            mAnswer = readPlyrLdr(mCtx, extras);
            rspPlayers(Constants.R_DB_READPLYRLDR, mAnswer, rInComing);
        }
        break;
    case Constants.S_DB_READPLYRREC :
        if (BuildConfig.DEBUG) {
            Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): S_DB_READPLYRREC received.");
        }
        synchronized (this) {
            // Get the New Sector Name from the bundle
            if (BuildConfig.DEBUG) {
                Log.i(Constants.TAG_CTLPLAYERS, "onHandleIntent(): S_DB_READPLYRREC received.");
            }
            mAnswer = readPlyrRec(mCtx, extras);
            rspPlayers(Constants.R_DB_READPLYRREC, mAnswer, rInComing);
        }
        break;
    } // end switch
}

IntentService.rspPlayers() [将结果发送回 FragmentActivity.ListFragment]:

private void rspPlayers(int mSignal, boolean mCode, ResultReceiver r) {
    if (BuildConfig.DEBUG) {
        Log.i(Constants.TAG_CTLPLAYERS, "respPlayers() called with signal, code: "+mSignal+", "+mCode);
    }

    Bundle resultData = new Bundle();
    switch (mSignal) {
    case Constants.R_DB_ADDPLYR :
        if (mCode == true) {
            resultData.putInt("reqStatus", Constants.R_TRUE_THAT);
        } else {
            resultData.putInt("reqStatus", Constants.R_NO_WAY);
        }
        break;
    case Constants.R_DB_READPLYRLDR :
        if (mCode == true) {
            resultData.putInt("reqStatus", Constants.R_TRUE_THAT);
            resultData.putInt("NumLdrRows", NumLdrRows);
            resultData.putSerializable("LPlyrList", LPlyrArray);
        } else {
            resultData.putInt("reqStatus",  Constants.R_NO_WAY);
        }
        break;
    case Constants.R_DB_READPLYRREC :
        if (mCode == true) {
            resultData.putInt("reqStatus", Constants.R_TRUE_THAT);
            resultData.putInt("NumRecRows", NumRecRows);
            resultData.putSerializable("RPlyrList", RPlyrArray);
        } else {
            resultData.putInt("reqStatus",  Constants.R_NO_WAY);
        }
        break;
    default :
        // do nothing
        break;
    }

    try {
        r.send(mSignal, resultData);
    } catch (java.lang.Exception e) {
        Log.e(Constants.TAG_CTLPLAYERS, "rspPlayers(): Exception message: "+e.getMessage());
        Log.e(Constants.TAG_CTLPLAYERS, "rspPlayers(): Exception cause: "+e.getCause());
        e.printStackTrace();
    }
}

【问题讨论】:

    标签: android sqlite fragment android-fragmentactivity intentservice


    【解决方案1】:

    我认为ArrayListFragmentReceiver 为空。

    Handler handler = new Handler();
    public EWTRReceiver ArrayListFragmentReceiver = new ResultReceiver(handler)
    

    需要处理程序来确保响应在原始线程中返回。否则这将是下一次崩溃。

    查看本教程以获取示例实现:

    http://ramdroid.github.io/androiddev/ResultReceiverDemo.html

    【讨论】:

    • 在我脑海中突出的那一行是“Intent intent = new Intent(getActivity(), CtlPlayers.class);”在 ArrayListFragment.callCtlr() 中。也许我的 IntentService 正在将结果发送回 FragmentActivity 而不是 ListFragment...?
    • 你是对的!我从来没有把它放在片段的 onCreate(): /** 实例化 ResultReceiver 以从 CtlSectors 接收消息到 this.onReceiverResult */ ActSectorsReceiver = new EWTRReceiver(new Handler()); ActSectorsReceiver.setReceiver(this);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2013-07-19
    • 2016-05-04
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多