Android 应用程序中逻辑和 GUI 的分离。服务了解应用程序,但不应该
我对 Android 编程来说是一个相对新手(我主要在 Windows 上使用 C#)。我继承了一些由服务和应用程序组成的代码。我想在另一个应用程序中重用该服务和一些应用程序。我把它放在图书馆里。除了一个问题之外,一切都很顺利。该服务有一些代码将主要活动显示在屏幕上。它通过名称呼出此活动。显然,我不能在通用代码中使用它。服务代码看起来像这样:
final int NOTIFY_1 = 0x1001;
NotificationManager notifier = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
final Notification notify = new Notification(
R.drawable.icon_my_color, ticker, System.currentTimeMillis());
notify.number = 1;
notify.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
notify.ledARGB = android.graphics.Color.CYAN;
notify.ledOnMS = 500;
notify.ledOffMS = 500;
Intent toLaunch = new Intent(context, MyBankingActivity.class);
toLaunch.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intentBack = PendingIntent.getActivity(context, 0, toLaunch, PendingIntent.FLAG_CANCEL_CURRENT);
notify.setLatestEventInfo(context, title, message, intentBack);
notifier.notify(NOTIFY_1, notify);
当发生一些有趣的事情(银行账户出现负值或其他情况)时,服务将运行此代码。问题是上面硬编码的“MyBankingActivity.class”。我已从库中删除了 MyBankingActivity,因为它是特定于应用程序的。但是,我确实必须让旧应用程序正常运行。我只是希望将其分为库和应用程序,以便我可以在另一个应用程序中重用库中的大量逻辑。在另一个应用程序中,我并不想特别收到此通知 “银行事件”。即使我这样做了,代码目前也是用一个活动的名称进行硬编码的。
这里分离逻辑的正确方法是什么?看起来该服务应该“发布”该事件,感兴趣的应用程序应该“订阅”。至少这是我熟悉的术语。顺便说一句,目前,我刚刚注释掉了整个代码块,并且在旧应用程序中一切正常,当然除了收到此通知之外。
我意识到(并道歉)我的问题很广泛。由于“授人以鱼,不如授人以鱼”可能更好,因此请随意推荐更广泛地涵盖该主题的参考资料/文章/书籍。我尝试自己查看有限的图书馆,但要么我的书太介绍性(《Android in Action》就是其中之一),要么我找错了地方。甚至连建立图书馆和写作服务的话题似乎也很难谈及。在我看来,有几个关键概念是我不擅长的: 1. 服务如何在不了解应用程序的情况下将事件传递给感兴趣的应用程序 2. 如何根据从服务收到的消息将应用程序带到前台 3. 如何获取现有应用程序并进入库(用于非 GUI 或非应用程序特定的内容)和应用程序。 4. 通知如何工作......
提前非常感谢, 戴夫
I'm a relative novice to Android programming (I mostly do C# on Windows). I inherited some code that consists of a service and app. I'd like to reuse the service and some of the app in another app. I'm putting that in a library. All has gone well except for one problem. The Service has some code that puts the main activity up on the screen. It calls out this activity by name. Clearly, I can't have that in common code. The service code looks something like this:
final int NOTIFY_1 = 0x1001;
NotificationManager notifier = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
final Notification notify = new Notification(
R.drawable.icon_my_color, ticker, System.currentTimeMillis());
notify.number = 1;
notify.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
notify.ledARGB = android.graphics.Color.CYAN;
notify.ledOnMS = 500;
notify.ledOffMS = 500;
Intent toLaunch = new Intent(context, MyBankingActivity.class);
toLaunch.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intentBack = PendingIntent.getActivity(context, 0, toLaunch, PendingIntent.FLAG_CANCEL_CURRENT);
notify.setLatestEventInfo(context, title, message, intentBack);
notifier.notify(NOTIFY_1, notify);
This code gets run by the service when something interesting happens (bank account goes negative or something). The problem is the "MyBankingActivity.class" that is hardcoded above. I have removed MyBankingActivity from the library because it's application specific. However, I do have to have the old app working. I just want it to be separated into a library and app so I can resuse the considerable logic in the library in another app. In that other app, I don't particulary want to be notified of this
"banking event". Even if I did, the code is currently hardcoded with one activity's name.
What is the correct way to separate the logic here? It would seem that the service should be "publishing" the event, and apps that are interested should "subscribe". At least that is the terminology I am familiar with. Incidentally, for now, I have just commented out the entire block of code and everything works fine in the old app, except of course getting this notification.
I realize (and apologize) that my question is broad. As it might be better to "teach a man to fish, rather than give him fish", please feel free to recommend references/articles/books that cover this topic more broadly. I have tried to look at my limited library on my own, but either my books are too introductory (Android in Action is one) or I'm looking in the wrong places. Even the topics of setting up libraries and writing services seem hard to come by. As I see it, there are a few key concepts I'm weak on:
1. How does a service communicate events to apps that are interested without knowledge of an app
2. How can an app be brought to the foreground based on some message received from service
3. How to take an existing app and break into a library (for non-gui or non app specific stuff) and app.
4. How notifications work....
Many thanks in advance,
Dave
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该服务正在向用户发布事件。
这取决于你如何定义“正确”。在这种情况下,我可能会将
PendingIntent
与Notification
一起使用,作为用于启动服务的Intent
的额外内容。PendingIntent
实现了Parcelable
,因此可以很好地融入到Intent
extra 中。通过这种方式,客户端可以决定当用户点击通知
时会发生什么——所有服务
需要做的就是在相关时显示通知
。此处介绍的用例不相关的应用程序的情况下向感兴趣的应用程序传达事件。您没有将事件从服务传送到应用程序。您正在将服务中的事件传达给用户。用户不是应用程序。
话虽这么说,您可以发送广播,或者让客户端传递一些内容作为
Intent
额外内容,用作回调机制(例如,PendingIntent
、Messenger )。
该服务调用
startActivity()
。请注意,如果用户发现您这样做很烦人(例如,在游戏中弹出一个活动),他们可能会以您不喜欢的方式发泄他们的挫败感。您目前采用的方法(显示
通知
)在大多数情况下是正确的。对于任何值得一提的操作系统,这都无法抽象地回答。
文档中对此进行了介绍 以及大多数 Android 入门书籍。
The service is publishing the event, to the user.
That depends on how you define "correct". In this case, I'd probably pass the
PendingIntent
to be used with theNotification
as an extra on theIntent
you used to start the service.PendingIntent
implementsParcelable
and therefore goes nicely into anIntent
extra. This way the client dictates what happens when the user taps theNotification
-- all theService
needs to do is display theNotification
when relevant.That is not relevant for your use case presented here. You are not communicating an event from a service to an app. You are communicating an event from a service to the user. The user is not an app.
That being said, you can send a broadcast, or have the client pass something as an
Intent
extra that will serve as a callback mechanism (e.g.,PendingIntent
,Messenger
).The service calls
startActivity()
. Note that users who find you annoying for doing this (e.g., popping up an activity in the middle of their game) may vent their frustration in ways that you will not appreciate.The approach you are presently taking -- displaying a
Notification
-- is the correct one in most cases.That cannot be answered in the abstract, for any operating system worth mentioning.
That is covered in the documentation and most introductory Android books.
这与
Intent
有更多关系,因为它是实际启动其他活动的代码行。你有一个
That 会告诉系统“我想对名为:...的活动做一些事情”
作者给出的意图名称已经告诉你会发生什么。
然后,意图会收到几个标志
(长话短说),它们确保活动如果仍在后台某处运行(或者更准确地说,如果它在历史堆栈上),则被带到前面。
然后是 PendingIntent
我对 PendingIntent 不太熟悉,但我认为它在这里没有正确使用。
至于你的问题:
1)您可以创建意图并让应用程序为其注册侦听器
2)这就是意图所做的事情,它告诉系统将该活动带到前台(或者您可以在意图上使用标志设置其他内容)
3) 取决于应用程序/代码
4) http://developer.android.com /reference/android/app/NotificationManager.html
在那里您还应该找到有关所有其他主题的信息
this has more to do with
Intent
as it is the line of code that actually starts the other activity.You have an
That will tell the system "i want to do something with the activity named: ..."
The name of the intent given by the author already tells you what will happen.
The intent then receives a couple of flags
(long story short) they make sure the activity is brought to front if it still was running somewhere in the background (or to be more precise, if it was on the history stack).
And then comes the PendingIntent
Im not so familiar with the PendingIntent but i think its not used the right way here.
As for your questions:
1) you can create intents and have apps register a listener for them
2) thats the thing the intent does, it tells the system to bring that activity to the foreground (or other things you can set with flags on the intent)
3) depends on the app/code
4) http://developer.android.com/reference/android/app/NotificationManager.html
there you should also find info on all the other topics