从 Activity 到 Service 的本地服务绑定代码

发布于 2024-12-20 00:10:10 字数 2749 浏览 2 评论 0原文

用于绑定到服务的客户端代码,通常位于活动类中;我正在尝试将其移至服务类,以便活动类尽可能干净且小。

即基本上尝试将这里第二个框中的代码合并到第一个框中=尽可能多地放入服务类中

Activity 中的单行用于绑定到服务

public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // Bind to service with this line only:
    AService.bindService(this);
}
}

静态 bindService 和 ServiceConnection 已移至服务

public class AService extends Service {

public String test = "I want to see this";
public static AService aService;
private static boolean isBound;
private static Context context;

// ... IBinder, onBind etc also here on service side

public static void bindService(Context context) {
    try {
        Log.i(TAG, "bindService Start");
        if (!isBound && context != null) {
            Log.i(TAG, "Binding");
            context.bindService(new Intent(context, AService.class),
                    serviceConnection, Context.BIND_AUTO_CREATE);
            isBound = true;
            Log.i(TAG, "Bound");
        }
    } catch (Exception e) {
        Log.e(TAG, "bindService", e);
    }
}

private static ServiceConnection serviceConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        try {
            Log.i(TAG, "onServiceConnected Start");
            aService = ((AService.LocalBinder) service).getService();
            if (aService != null)
                Log.i(TAG, aService.test);
            Log.i(TAG, "onServiceConnected Finish");
        } catch (Exception e) {
            Log.e(TAG, "onServiceConnected", e);
        }
    }

    public void onServiceDisconnected(ComponentName className) {
        try {
            Log.i(TAG, "onServiceDisconnected");
            aService = null;
        } catch (Exception e) {
            Log.e(TAG, "onServiceDisconnected", e);
        }
    }
};


public static void unbind() {
    try {
        Log.i(TAG, "unbind start");
        if (isBound && context != null) {
            Log.i(TAG, "Unbinding");
            context.unbindService(serviceConnection);
            isBound = false;
            context = null;
            Log.i(TAG, "Unbound");
        }
    } catch (Exception e) {
        Log.e(TAG, "unbind", e);
    }
}

}

但从未调用 onServiceConnected?

日志显示以下所有内容:

...
Bound
  • NOT onServiceConnected Start 或更高版本
  • ,没有例外。
  • 请注意,当相同的代码在 Activity 中时,它可以工作(当使用 MyActivity.this 调用时)

我做错了什么?

The client code for binding to a service, which is normally in the activity class; I'm trying to move it to the service class, so that the activity class would be as clean and small as possible.

i.e. basically trying to merge the code in the second box here into the first box = as much of it into the service class as possible

Single Line in Activity for Binding to Service

public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // Bind to service with this line only:
    AService.bindService(this);
}
}

Static bindService and ServiceConnection Moved to Service

public class AService extends Service {

public String test = "I want to see this";
public static AService aService;
private static boolean isBound;
private static Context context;

// ... IBinder, onBind etc also here on service side

public static void bindService(Context context) {
    try {
        Log.i(TAG, "bindService Start");
        if (!isBound && context != null) {
            Log.i(TAG, "Binding");
            context.bindService(new Intent(context, AService.class),
                    serviceConnection, Context.BIND_AUTO_CREATE);
            isBound = true;
            Log.i(TAG, "Bound");
        }
    } catch (Exception e) {
        Log.e(TAG, "bindService", e);
    }
}

private static ServiceConnection serviceConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        try {
            Log.i(TAG, "onServiceConnected Start");
            aService = ((AService.LocalBinder) service).getService();
            if (aService != null)
                Log.i(TAG, aService.test);
            Log.i(TAG, "onServiceConnected Finish");
        } catch (Exception e) {
            Log.e(TAG, "onServiceConnected", e);
        }
    }

    public void onServiceDisconnected(ComponentName className) {
        try {
            Log.i(TAG, "onServiceDisconnected");
            aService = null;
        } catch (Exception e) {
            Log.e(TAG, "onServiceDisconnected", e);
        }
    }
};


public static void unbind() {
    try {
        Log.i(TAG, "unbind start");
        if (isBound && context != null) {
            Log.i(TAG, "Unbinding");
            context.unbindService(serviceConnection);
            isBound = false;
            context = null;
            Log.i(TAG, "Unbound");
        }
    } catch (Exception e) {
        Log.e(TAG, "unbind", e);
    }
}

}

But onServiceConnected is Never Called?

The log shows everything up to:

...
Bound
  • But NOT onServiceConnected Start or beyond
  • and no exceptions.
  • Note that when the same code was in the Activity, it works (when called with MyActivity.this)

What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄凉少年不暖心 2024-12-27 00:10:10

AService.bindService(this);

比这个好很多吗?

bindService(new Intent(context, AService.class),
                serviceConnection, Context.BIND_AUTO_CREATE);

位于 Activity 中的 ServiceConnection 实现真的让您如此烦恼吗?我对此表示怀疑。

我不认为有任何必要将所有内容集中到服务中,然后在实际服务中调用静态方法来从活动启动该服务。最佳实践是遵循 Google 建议的标准做事方式,按照您的方式这样做,您的代码会变得晦涩难懂,并使其他人在阅读您的代码时感到困惑(如果您在团队中工作)。国际海事组织这没有任何意义。

与其把所有的精力都花在把每一个服务与 Activity 隔离开来,我宁愿更多地考虑如何将业务逻辑与 Activity 隔离并集中到服务中,让 Activity 主要关注 UI 的东西。

真的希望这能帮助你。

Is this

AService.bindService(this);

much better than this?

bindService(new Intent(context, AService.class),
                serviceConnection, Context.BIND_AUTO_CREATE);

And does ServiceConnection implementation sit in Activity really annoying your so much? I doubt that.

I don't see any point centralize everything into Service and then call a static method in the actual Service to start this Service from Activity. The best practice is to follow the standard way that Google's recommended to do things, by doing this in your way, you make your code obscure and confuse other people when reading your code (if you work in a team). It doesn't make any sense IMO.

Instead of put all your effort into isolate every single bit of service from activity, I would rather consider more on how to isolate business logic from activity and centralize them into service, and let Activity mostly focus on UI stuff.

Really hope that would help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文