草庐IT

java - Android - 为什么此服务的多个实例正在运行

coder 2023-12-22 原文

我已经编写了一项服务,我计划让多个应用程序使用 Messenger 与其通信。我遵循了 Android Bound Services example for messenger 中的示例. 我已将该服务放入一个 Android 库项目中,所有其他 Android 项目都使用该库。

我遇到的问题是,当我绑定(bind)到该服务时,它会运行多个服务实例。每个应用程序都以下列方式绑定(bind)到服务:

// Bind to the service
bindService(new Intent(ApplicationOneActivity.this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);

服务是:

public class MessengerService extends Service {
    /** Command to the service to display a message */
    public static final int MSG_SAY_HELLO = 0;
    /** Command to the service to display a message from App 1 */
    public static final int MSG_APP1_HELLO = 1;

    public static final int MSG_APP2_HELLO = 2;

    public static final int MSG_APP3_HELLO = 3;

    private int[] stat = new int[3];

    private Timer timer = null;

    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_SAY_HELLO:
                Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                break;
            case MSG_APP1_HELLO:
                Toast.makeText(getApplicationContext(), "App One says: " + msg.arg1, Toast.LENGTH_SHORT).show();
                stat[0] = msg.arg1;
                break;
            case MSG_APP2_HELLO:
                Toast.makeText(getApplicationContext(), "App Two says: " + msg.arg1, Toast.LENGTH_SHORT).show();
                stat[1] = msg.arg1;
                break;
            case MSG_APP3_HELLO:
                Toast.makeText(getApplicationContext(), "App Three says: " + msg.arg1, Toast.LENGTH_SHORT).show();
                stat[2] = msg.arg1;
                break;
            default:
                super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();

        return mMessenger.getBinder();

    }

    @Override
    public boolean onUnbind(Intent intent) {
        Toast.makeText(getApplicationContext(), "unbinding", Toast.LENGTH_SHORT).show();
        return super.onUnbind(intent);
    }

    final Handler handler = new Handler() {

        public void handleMessage(Message msg) {
            // Create and send a message to the service, using a supported 'what' value
            ReportAsyncTask report = new ReportAsyncTask();
            report.execute("");
        }
    };


    @Override
    public void onCreate() {
        super.onCreate();

        if (timer == null) {
            timer = new Timer();
            timer.schedule(new ScheduledTaskWithHandeler(), 10000);
            Toast.makeText(getApplicationContext(), "Register Timer To Report Back ", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    class ScheduledTaskWithHandeler extends TimerTask {

        @Override
        public void run() {
            handler.sendEmptyMessage(0);
        }
    }

    private class ReportAsyncTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            String response = "";
            try {
                String urlParams="device=" + URLEncoder.encode(android.os.Build.MODEL, "UTF-8")
                        + "&status="+URLEncoder.encode("App1 says " + stat[0] + ", App2 says " + stat[1] + ", App3 says " + stat[2],"UTF-8");
                String url = "http://192.168.43.143:8080/SimpleServlet3/monitor-servlet";
                HttpClient httpclient = new DefaultHttpClient();
                HttpGet httpget = new HttpGet(url+"?"+urlParams);
                HttpResponse httpresponse = httpclient.execute(httpget);
                HttpEntity entity = httpresponse.getEntity();
                if (entity != null) {
                    InputStream instream = entity.getContent();
                    int l;
                    byte[] tmp = new byte[2048];
                    while ((l = instream.read(tmp)) != -1) {
                        response += l;
                    }
                }
                timer.schedule(new ScheduledTaskWithHandeler(), 10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return response;
        }

        @Override
        protected void onPostExecute(String result) {
            Toast.makeText(getApplicationContext(), "Server says " + result, Toast.LENGTH_SHORT).show();
        }

    }

}

每个应用程序的 list 看起来更像是:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app1"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="11" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application
        android:icon="@drawable/spinifex"
        android:label="@string/app_name" >
        <activity
            android:name=".ApplicationOneActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <service
            android:name="com.example.services.MessengerService"
            android:process=":remote" />
    </application>

</manifest>

知道我做错了什么吗? Toast 消息非常明确地表明同一服务的多个实例正在运行。我的项目结构错了吗?我不应该把服务放在一个单独的图书馆项目中吗?

最佳答案

您必须声明 <service />仅在一个 AndroidManifest 中标记,而在其他应用中,您必须通过完整的组件名称进行绑定(bind)。 如:

Intent intent = new Intent();
intent.setClassName(
  "com.example.app1" /* your package which contains service */,
  "com.example.services.MessengerService" /* service name */
);

bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

另外,当你做 android:process=":remote" ,您告诉 android 该进程对当前应用程序是私有(private)的。

关于java - Android - 为什么此服务的多个实例正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10024133/

有关java - Android - 为什么此服务的多个实例正在运行的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  3. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  4. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  5. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  6. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  7. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  8. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  9. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  10. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

随机推荐