【问题标题】:Explicit and Implicit intents显式和隐式意图
【发布时间】:2017-07-29 04:14:15
【问题描述】:

我对意图有点困惑。

为什么

Intent implicit=new Intent(IDownload.class.getName());  

一个隐式意图

同时

Intent explicit=new Intent(implicit);  

是一个显式意图,而它似乎并没有在其定义中添加任何新内容。系统似乎没有绘制任何先前未由上述implicit 意图提供的新信息?

Android documentation (Intent types)

显式意图指定组件以名称(完全限定的类名)开头。您通常会使用显式意图在您自己的应用程序中启动一个组件,因为您知道要启动的活动或服务的类名......

Intent implicit=new Intent(IDownload.class.getName()); 似乎满足此要求,但仍被视为隐式意图,根据文档:

隐式意图不命名特定组件,而是声明要执行的一般操作,这允许来自另一个应用程序的组件处理它.....

Intent explicit=new Intent(implicit); 似乎与此相矛盾,但仍被视为显式意图。

更新 - 示例实现

参考:Binding to a Service

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

  setRetainInstance(true);

  appContext=(Application)getActivity().getApplicationContext();

  Intent implicit=new Intent(IDownload.class.getName());
  List<ResolveInfo> matches=getActivity().getPackageManager()
  .queryIntentServices(implicit, 0);

  if (matches.size() == 0) {
    Toast.makeText(getActivity(), "Cannot find a matching service!",
      Toast.LENGTH_LONG).show();
  }
  else if (matches.size() > 1) {
    Toast.makeText(getActivity(), "Found multiple matching services!",
      Toast.LENGTH_LONG).show();
  }
  else {
    ServiceInfo svcInfo=matches.get(0).serviceInfo;

    try {
      String otherHash=SignatureUtils.getSignatureHash(getActivity(),
        svcInfo.applicationInfo.packageName);
      String expected=getActivity().getString(R.string.expected_sig_hash);

      if (expected.equals(otherHash)) {
        Intent explicit=new Intent(implicit);
        ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName,
          svcInfo.name);

        explicit.setComponent(cn);
        appContext.bindService(explicit, this, Context.BIND_AUTO_CREATE);
      }
      else {
        Toast.makeText(getActivity(), "Unexpected signature found!",
          Toast.LENGTH_LONG).show();
      }
    }
    catch (Exception e) {
      Log.e(getClass().getSimpleName(), "Exception trying to get signature hash", e);
    }
  }
}

【问题讨论】:

  • 是什么让你说Intent explicit=new Intent(implicit); 是一个明确的意图?
  • 在那个例子中,在他调用explicit.setComponent(cn)之前,意图仍然是一个隐含的意图。使意图明确的是组件名称的设置;他只是将变量命名为explicit,因为几行就可以了。
  • 处理组件在以下代码中设置,使 Intent 显式。

标签: java android android-intent


【解决方案1】:

链接的示例包括这些行

      Intent explicit=new Intent(implicit);
      ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName,
        svcInfo.name);

      explicit.setComponent(cn);

第一行只是创建一个新的Intent 实例,它是旧实例的副本。虽然变量可能是explicit,但在这个时间点上,它仍然是一个隐含的意图。

第二行基于之前getActivity().getPackageManager().queryIntentServices(implicit, 0) 调用的单个匹配结果创建了一个ComponentName 对象。此时,explicit 仍然是一个隐含意图。

第三行是魔法。一旦将特定的ComponentName 分配给Intent 实例,explicit 就真正成为一个明确的意图。

【讨论】:

  • IDownload.class.getName() 这不是完全限定的类名 - Android documentation (Intent types)
  • Class.getName() 返回一个String,这意味着您正在使用Intent(String) 构造函数。在这种情况下,字符串是“动作”,它不是“完全限定的类名”。您需要使用 Intent(Context, Class)Intent(String, Uri, Context, Class) 构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
相关资源
最近更新 更多