7

我正在 Android 中实现一个 REST 客户端。我已经看到了一个使用 aService执行与服务器的连接并ResultReceiver通知操作完成的示例。我正在从片段调用服务,如果我在服务运行时尝试旋转屏幕,getActivity() 方法会ResultReceiver返回 null,因为该片段可能不再处于布局中。

片段中的回调方法:

@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
    Response response = (Response) resultData
            .getSerializable(RestService.RESULT);
    if (resultCode == RestService.SUCCESS
            && response != null) {
        if (getActivity() != null) {
            recommendationResponse = response;
            getLoaderManager().restartLoader(0, new Bundle(),
                    Fragment.this);
        }

    }
}

getActivity()返回空值。这是正常的吗?即使在屏幕旋转时,我可以使用什么方法来允许通知?本地广播?

4

5 回答 5

13

不,

android:configChanges="orientation"

不是解决方案。

要使用 ResultReceiver I:

  • 将其保存在方向更改上:

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putParcelable(Consts.RECEIVER, mReceiver);
        super.onSaveInstanceState(outState);
    }
    
  • 重置接收器:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    
        if (savedInstanceState != null) {
            mReceiver = savedInstanceState.getParcelable(Consts.RECEIVER);
        }
        else {
            mReceiver = new MyResultReceiver(new Handler());
        }
        mReceiver.setReceiver(this);
    }
    

这是我的 ResultReceiver 类:

import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;

public class MyResultReceiver extends ResultReceiver {
    private Receiver mReceiver;

    public MyResultReceiver(Handler handler) {
        super(handler);
    }

    public void setReceiver(Receiver receiver) {
        mReceiver = receiver;
    }

    public interface Receiver {
        public void onReceiveResult(int command, Bundle resultData);
    }

    @Override
    protected void onReceiveResult(int command, Bundle resultData) {
        if (mReceiver != null) {
            mReceiver.onReceiveResult(command, resultData);
        }
    }
}
于 2014-04-14T11:47:46.130 回答
1

我正在使用BroadcastReceiver注册的使用LocalBroadcastManager,它工作正常。这不是那么简单。是否存在更好的解决方案?

于 2012-06-07T13:23:59.157 回答
1

我想我偶然发现了同样的问题,并通过在我的 ResultReceiver 的 onReceivedResult 方法中验证 NULL 来解决它。此处发布的代码适用于工作片段(没有 UI 的片段和 onCreate 中的 setRetainInstance(true))

protected void onReceiveResult(int resultCode, Bundle resultData) {
            //Verify activity
            if(getActivity() != null){
                //Handle result
            }else{
                notificationPending = true;                 
            }
        }

如果未找到活动(活动在片段分离上不可用),则 notificationPending 标志可帮助片段保持未决通知。

当片段重新附加到活动时,我执行此逻辑

public void onAttach(Activity activity){
    super.onAttach(activity);
        if(notificationPending){
            //Handle notification
            notificationPending = false;
        }
}

希望能帮助到你。如果您愿意,可以询问更多详细信息。干杯

于 2012-09-29T19:10:44.113 回答
0

是的,这很正常,因为 ResultReceiver 可能是“无头的”。

我尝试保存ResultReceiverat onSaveInstanceState(),但它没有用,因为更新,在接收Fragment被破坏时发生,丢失,以及对回调的引用。

可以在这里找到解释和可能的解决方案:https ://stanmots.blogspot.com/2016/10/androids-bad-company-intentservice.html

关于这个问题的另一个好读物: https ://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

我的完整解决方案如何使用 aResultReceiver可以在这里找到: https ://stackoverflow.com/a/54334864/6747171

于 2019-01-23T20:30:11.627 回答
-1

getActivity() 返回 null。这是正常的吗?

Android 活动在设备旋转后重新创建。

重新创建活动后,它不包含旧的上下文。这就是为什么你得到 getActivity()null

即使在屏幕旋转时,我可以使用什么方法来允许通知?本地广播?

如果您不想在屏幕旋转上重新创建活动,请在清单中提及以下内容

        <activity
            android:name=".MyActivity"
            android:configChanges="orientation"    <<<<<<<<<
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

最后,您必须在 Activity 中覆盖以下内容。

@Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        // TODO Auto-generated method stub
        super.onConfigurationChanged(newConfig);
    }
于 2012-06-07T07:54:23.520 回答