ARChon 分析之二:简单分析与Chrome插件介绍

版权声明:转载请邮件联系我([email protected]),以取得授权,谢谢! https://blog.csdn.net/yeshennet/article/details/83049354

源码在这里:

ARChon 插件: https://bitbucket.org/vladikoff/archon/src
https://github.com/vladikoff/chromeos-apk

第一眼的判断

上一篇博客中,可以知道,有几个步骤
一是安装 ARChon 插件。
二是对现有的Android应用做转化,使之符合Chrome App的要求。
三是使用一中的插件来加载二中的应用。

下载插件的源码下来看之后,发现除了几个js文件,其他都是本地的so包。so库文件应该是从ChromeOS 这个项目来的。
所以分析的重点主要集中在步骤三,可能读完这几个js文件,重点要放在这些so库上。

Chrome 插件

但是在这之前,我们需要简单的了解下Chrome插件是什么?怎么开发?

https://crxdoc-zh.appspot.com/extensions/getstarted
https://crxdoc-zh.appspot.com/extensions/overview
https://crxdoc-zh.appspot.com/extensions/tut_debugging

玩~


以下只是复制


扩展程序允许您为 Chrome 浏览器增加功能,而不需要深入研究本机代码。您可以使用您在网页开发中已经很熟悉的核心技术(HTML、CSS 与 JavaScript)为 Chrome 浏览器创建新的扩展程序。如果您曾经编写过网页,您应该很快熟悉扩展程序的开发。现在我们将证明这一点,引导您创建一个简单的扩展程序,使您通过一次点击就能访问猫的图片。猫啊!

我们将实现一种我们称之为浏览器按钮的用户界面元素,使我们能够将一个可以单击的按钮放在 Chrome 浏览器多功能框的右边,这样可以轻松地访问。单击这一图标将打开一个弹出的窗口,包含很多猫,如下图所示:

Chrome, with an extension’s popup open and displaying many kittens.
如果您现在就想跟着一步一步走(您应该这样!),请在您的计算机上创建一个全新的目录,打开您最喜欢的文本编辑器,让我们开始吧!

要声明的内容
我们需要创建的第一个文件是一个清单文件,名为 manifest.json。清单文件只不过是一个 JSON 格式的目录,包含一些属性,如您的扩展程序的名称与描述、它的版本号等等。从更高的层次来看,我们将使用它来向 Chrome 浏览器声明扩展程序将会做什么,以及为了完成这些任务所需要的权限。

为了显示猫,我们将告诉 Chrome 浏览器我们要创建一个浏览器按钮,我们还希望自由访问来自网络上某个特定来源的猫。包含这些指令的清单文件如下所示:

{
  "manifest_version": 2,

  "name": "One-click Kittens",
  "description": "This extension demonstrates a browser action with kittens.",
  "version": "1.0",

  "permissions": [
    "https://secure.flickr.com/"
  ],
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  }
}

接下来,将这一数据保存在名为 manifest.json 的文件中,放在您创建的目录中,或者从我们的示例库中下载 manifest.json 的一份拷贝。

它的含义是什么?
属性名称非常具有自我描述性,但是还是让我们一行一行地介绍清单文件,确保我们对此的理解一致。

第一行声明我们使用清单文件格式的版本 2,必须包含(版本 1 是旧的,已弃用,不建议使用)。

接下来的部分定义扩展程序的名称、描述与版本。这些都会在 Chrome 浏览器中使用,向用户显示已安装的扩展程序,同时在 Chrome 网上应用店中向潜在的新用户显示您的扩展程序。名称应该简练,描述不要比一句话左右还长(后面您将会有更多的空间用于更详细的描述)。

最后一部分首先请求权限,用于访问 https://secure.flickr.com/ 上的数据,并声明该扩展程序实现了一个浏览器按钮,同时在这一过程中为它指定一个默认图标与弹出窗口。

资源
您可能已经注意到,manifest.json 定义浏览器按钮时指向了两个资源文件:icon.png 与 popup.html。这两个资源都必须在扩展程序包中存在,所以让我们现在创建它们:

The popup’s icon will be displayed right next to the Omnibox. icon.png 将会显示在多功能框旁边,等待用户交互。从我们的示例库中下载 icon.png 的一份拷贝,并将它保存在您正在工作的目录中。如果您愿意的话也可以自己创建,这只是一个 19×19 像素的 PNG 文件。

The popup’s HTML will be rendered directly below the icon when clicked. popup.html 将会在响应用户对浏览器按钮的单击时创建的弹出窗口中渲染。这是一个标准的 HTML 文件,就像您在网页开发中熟悉的那样,给了您或多或少的自由,决定弹出窗口显示的内容。从我们的示例库中下载 popup.html 的一份拷贝,并将它保存在您正在工作的目录中。

popup.html 需要额外的 JavaScript 文件才能从网上获取猫的图片,并在弹出窗口中加载它们。为了使您少费些力气,只要从我们的示例库中下载 popup.js 的一份拷贝,并将它保存在您正在工作的目录中。

现在在您工作的目录中应该有四个文件: icon.png、manifest.json、popup.html、popup.js。下一步是将这些文件加载到 Chrome 浏览器中。

加载扩展程序
您从 Chrome 网上应用店下载的扩展程序打包为 .crx 文件,便于发布,但是不便于开发。注意到了这一点,Chrome 浏览器为您提供了一种方式,可以加载您的工作目录用于测试。现在让我们来试试。

在您的浏览器中访问 chrome://extensions(或者单击多功能框最右边的按钮: The menu’s icon is three horizontal bars.打开 Chrome 浏览器菜单,并选择工具(L)菜单下的扩展程序(E),进入相同的页面)。

确保右上角开发者模式复选框已选中。 Ensure that the Developer mode checkbox in the top right-hand corner is checked.

单击加载正在开发的扩展程序…,弹出文件选择对话框。

浏览至您的扩展程序文件所在的目录,并选定。

您也可以将扩展程序文件所在的目录拖放到浏览器中的 chrome://extensions 上加载它。

如果扩展程序有效的话,它将被加载并且立刻处于活动状态!如果无效的话,页面顶部将显示错误消息,请纠正错误再重试。

修改代码
现在您已经准备好了您的第一个扩展程序,并使它运行。让我们做一些修改,以便使您了解开发过程会是什么样的。举一个普通的例子,让我们更改数据源以搜索小狗而不是猫的图片。

进入 popup.js,并编辑第 11 行,将 var QUERY = ‘kittens’; 改为 var QUERY = ‘puppies’;,并保存更改。

如果您再次单击您的扩展程序的浏览器按钮,您会注意到您的更改还没有效果。您需要让 Chrome 浏览器知道发生了更改,既可以回到扩展程序页面(chrome://extensions 或 Chrome 浏览器菜单下的工具(L) > 扩展程序)并单击您的扩展程序下的重新加载,也可以重新加载扩展程序页面本身(通过多功能框左边的的重新加载按钮或者按下 F5 或 Ctrl-R)。

一旦您重新加载扩展程序后,再次单击浏览器按钮。好多小狗啊!

接下来做什么?
您现在了解了扩展程序的中心地位,可以将其他内容整合在一起,您也已经掌握了声明浏览器按钮、响应用户单击而呈现一些猫(或小狗!)的基本内容。这是一个良好的开端,希望也使您产生了足够的兴趣,进一步探索。有很多资源可以参考。

Chrome 扩展程序概述进一步地进行了介绍,并包含扩展程序大致架构的许多细节,还包含了您接下来可能希望熟悉的某些特定概念。这是您掌握扩展程序开发过程中接下来最合适的一步。

没有人第一次尝试时就能写出完美的代码,这意味着您需要了解调试您的作品时可用的选项。我们的调试教程非常合适,很值得仔细读一读。

Chrome 扩展程序能够访问强大的 API,远远超过了普通网页可用的部分:浏览器按钮就是冰山一角。我们的 chrome.* API 文档将带您一步一步了解每一个 API。

最后,开发者指南包含许多额外的链接,指向您可能感兴趣的文档。


概述
当您看完该页面以及入门教程后,您已经准备好开始编写扩展程序了。

基础
扩展程序由一些文件(包括 HTML、CSS、JavaScript、图片以及其他任何您需要的文件)经过 zip 打包得到,为 Google Chrome 浏览器增加功能。扩展程序本质上是网页,它们可以利用浏览器为网页提供的所有 API,例如 XMLHttpRequest、JSON、HTML 5 等等。

扩展程序可以通过内容脚本或跨站 XMLHttpRequest 与网页或者服务器交互,扩展程序也可以以编程方式与浏览器功能(例如书签和标签页交互)。

扩展程序的用户界面
许多扩展程序(但不包括 Chrome 应用)以浏览器按钮或页面按钮的形式向 Google Chrome 浏览器增加用户界面,每个扩展程序最多能有一个浏览器按钮或页面按钮。当扩展程序与大部分网页相关时选择使用浏览器按钮,当扩展程序的图标显示还是消失取决于具体网页时选择使用页面按钮。

screenshot screenshot screenshot
这一Google Mail Checker 扩展程序使用浏览器按钮(工具栏中的图标)。 这一Mappy 扩展程序使用页面按钮(地址栏中的图标)以及内容脚本(插入网页的代码)。 单击时显示弹出菜单的浏览器按钮是这一新闻阅读器扩展程序的特色。
扩展程序(以及 Chrome 应用)也可以以其他形式呈现用户界面,例如在 Chrome 浏览器的右键菜单中添加内容,提供选项页面,或者利用内容脚本更改页面的显示方式。有关完整的扩展程序功能以及每一种功能的实现细节,请参见开发者指南。

文件
每一个扩展程序包含以下文件:

一个清单文件
一个或多个 HTML 文件(除非扩展程序是一个主题背景)
可选:一个或多个 JavaScript 文件
可选:您的扩展程序需要的任何其他文件,例如图片
当您编写您的扩展程序时,您将所有这些文件放在一个文件夹中。当您发布您的扩展程序时,该文件夹的内容将被压缩成一个特殊的 ZIP 文件,以 .crx 为后缀。如果您通过 Chrome 开发者信息中心上传您的扩展程序,该 .crx 文件会自动为您创建。有关发布扩展的细节,请参见托管。

引用文件
您可以在扩展程序中放置您需要的任何文件,但是您如何使用它们呢?通常,您可以通过相对 URL 引用文件,就像在普通的 HTML 页面中那样。下面是一个例子,引用位于子文件夹 images 中名为 myimage.png 的文件。

您使用 Google Chrome 浏览器的调试器时可能会发现,扩展程序中的每一个文件也可以通过绝对 URL 访问,如下所示:

chrome-extension://<扩展程序标识符>/<文件路径>
在这一 URL 中,<扩展程序标识符> 是扩展程序系统为每一个扩展程序生成的唯一标识符,您可以进入 chrome://extensions 查看您加载的所有扩展程序的标识符。<文件路径> 是扩展程序的主目录下的文件位置,与相对 URL 相同。

当您编写扩展程序时(打包之前),扩展程序标识符可能会更改。特别地,如果您从另一个目录加载未打包的扩展程序,它的标识符会改变,当您打包扩展程序时会再次改变。如果您的扩展程序代码需要指定扩展程序中某个文件的完整路径,您可以使用 @@extension_id 这一预定义消息,避免开发过程中硬编码标识符。

当您打包扩展程序时(典型情况下,通过信息中心上传),该扩展程序将会获得一个永久的标识符,即使您更新了这一扩展程序仍然保持不变。一旦扩展程序的标识符变成永久的了,您就可以将所有的 @@extension_id 修改为真正的唯一标识符。

清单文件
清单文件名为 manifest.json ,提供有关扩展程序的各种信息,例如最重要的文件和扩展程序可能具有的能力。以下是一个典型的清单文件,用于一个浏览器按钮,它将会访问来自 google.com 的信息:

{
  "name": "我的扩展程序",
  "version": "2.1",
  "description": "从 Google 获取信息。",
  "icons": { "128": "icon_128.png" },
  "background": {
    "persistent": false,
    "scripts": ["bg.js"]
  },
  "permissions": ["http://*.google.com/", "https://*.google.com/"],
  "browser_action": {
    "default_title": "",
    "default_icon": "icon_19.png",
    "default_popup": "popup.html"
  }
}

有关更多细节,请参见清单文件。

架构
许多扩展程序有一个后台网页,它是一个包含扩展程序主要逻辑的不可见页面。扩展程序也可以包含其他页面,展现扩展程序的用户界面。如果扩展程序需要与用户加载的网页交互(相对于包含在扩展程序中的页面),扩展程序必须使用内容脚本。

后台网页
下图所示的浏览器至少安装了两个扩展程序:一个浏览器按钮(黄色图标)和一个页面按钮(蓝色图标)。浏览器按钮和页面按钮都有后台页面。下图显示了浏览器按钮的后台页面,由 background.html 定义,并且包含在这两个窗口中控制浏览器按钮的 JavaScript 代码。

Two windows and a box representing a background page (background.html). One window has a yellow icon; the other has both a yellow icon and a blue icon. The yellow icons are connected to the background page.
后台网页分两种:持续运行的后台网页与事件页面。正如它们的名称所述,持续运行的后台网页保持打开状态,事件页面根据需要打开与关闭。除非您绝对需要您的后台网页一直运行,请首选事件页面。

有关更多细节,请参见事件页面与后台网页。

用户界面网页
扩展程序可以包含普通的 HTML 网页,用来显示扩展程序的用户界面。例如,浏览器按钮可以包含弹出菜单,通过 HTML 文件实现。任何一个扩展程序都可以有选项页面,让用户自定义扩展程序的工作方式。另外一种特殊页面是替代页面。最后,您可以使用 tabs.create 或 window.open() 来显示扩展程序中的任何其他 HTML 文件。

扩展程序中的 HTML 网页可以互相访问其他页面的全部 DOM,并且可以互相调用函数。

下图显示了浏览器按钮弹出菜单的架构。弹出菜单是由一个 HTML 文件(popup.html)定义的网页,该扩展程序也正好有一个后台网页(background.html)。弹出窗口不用重复后台网页中的代码,因为弹出窗口可以调用后台网页上的函数。

A browser window containing a browser action that’s displaying a popup. The popup’s HTML file (popup.html) can communicate with the extension’s background page (background.html).
有关更多细节,请参见浏览器按钮、选项、替代页面和页面间通信这些部分。

内容脚本
如果您的扩展程序需要与网页交互,您就需要使用内容脚本。内容脚本是一些 JavaScript 代码,它们在浏览器中已加载页面的上下文中执行。您应该将内容脚本视为已加载页面的一部分,而不是打包在一起的扩展程序(它所属的扩展程序)的一部分。

内容脚本可以读取浏览器访问的网页的细节,并且可以修改页面。在下图中,内容脚本可以读取并且修改显示的网页的 DOM。然而,它不能修改所属扩展程序后台网页的 DOM。

A browser window with a browser action (controlled by background.html) and a content script (controlled by contentscript.js).
内容脚本并不是完全与所属扩展程序隔离的。内容脚本可以与所属扩展程序交换消息,如下图箭头所示。例如,每当在浏览器页面中发现 RSS 供稿时,内容脚本可以发送消息,反过来后台页面也可以发送消息要求内容脚本更改浏览器页面的外观。

Like the previous figure, but showing more of the parent extension’s files, as well as a communication path between the content script and the parent extension.
有关更多信息,请参见内容脚本。

使用 chrome.* API
扩展程序除了能够使用网页和应用可以使用的所有 API 外,还能使用仅用于 Chrome 浏览器的 API(通常称为 chrome.* API)来更好地与浏览器集成。例如,任何扩展程序或网上应用可以使用标准的 window.open() 方法来打开一个网页,但是如果您想指定网页应该显示在哪个窗口中,您的扩展程序就可以使用仅用于 Chrome 浏览器的 tabs.create 方法。

异步方法与同步方法的区别
大部分 chrome.* API 的方法都是异步的,它们不等待操作完成就立即返回。如果您需要知道操作结果,您可以向方法传递一个回调函数,回调函数将稍后在方法返回后的某个时刻执行(可能很久之后)。下面是一个异步方法签名的例子:

chrome.tabs.create(object createProperties, function callback)

也有一些 chrome.* 方法是同步的。同步的方法没有回调参数,因为它们只有当所有操作完成后才返回。通常,同步方法有返回值类型。考虑 runtime.getURL 方法:

string chrome.runtime.getURL()

该方法没有回调参数,但是有返回值类型 string,因为它同步地返回 URL,不进行任何其他异步操作。

例子:使用回调函数
假设您想在用户当前选定的标签页中打开新的页面。要想这么做,您首先需要获得当前标签页的标识符(使用 tabs.query),然后使该标签转到指定的新的 URL(使用 tabs.update)。

假如 query() 是同步的,您可能会写这样的代码:

//以下代码不能正常工作!
var tab = chrome.tabs.query({'active': true}); //错误!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

这样的方法不行,因为 query() 是异步的,它不等待操作完成就返回了,并且事实上它都不返回任何值(尽管有些异步方法会返回信息)。您可以通过它签名中的 callback参数看出 query() 是异步的:

chrome.tabs.query(object queryInfo, function callback)

要改正上面的代码,您必须使用那个回调参数。以下代码显示如何定义一个回调函数,从 query() 获得结果(通过名为 tab 的参数)并调用 update()。

//以下代码可以正常工作
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});

someOtherFunction();
在这一例子中,以上几行是按照这样的顺序执行的:1、4、2。只有在有关当前选定标签的信息可用后,即 query() 返回后的某一时刻,才调用在 query() 中指定的回调函数(并且执行第二行)。尽管 update() 是异步的,这一例子没有使用回调参数,因为我们对于调用的结果并不感兴趣。

更多详情
有关更多信息,请参见 chrome.* API 文档并观看以下视频(英文):

页面间的通信
扩展程序中的 HTML 网页通常需要通信。因为一个扩展程序的所有网页在同一个进程中的同一个线程上执行,网页之间可以直接调用函数。

要获得扩展程序中的网页,请使用 chrome.extension 方法,例如 extension.getViews 和 extension.getBackgroundPage。一旦一个网页引用了扩展程序中的其他网页,第一个网页可以执行其他网页上的函数,并且可以操纵它们的 DOM。

保存数据和隐身模式
扩展程序可以使用 storage API、HTML5 网页存储 API(例如 localStorage)或者向服务器发出请求保存数据。每当您要保存任何数据前,首先要考虑它是否来自隐身窗口。默认情况下,扩展程序不在隐身窗口中运行。当浏览器处于隐身模式时,您需要考虑用户对您的扩展程序的需求。

隐身模式确保不会留下任何痕迹。当处理来自隐身窗口的数据时,尽可能地遵守这一约定。例如,如果您的扩展程序通常将浏览器历史记录保存至云端,不要保存来自隐身窗口的历史记录。另一方面,您可以在任何窗口中保存您的扩展程序设置,无论隐身与否。

准则: 如果某些数据可能显示用户在网上的访问记录或者用户所做的事情,千万不要保存这些来自隐身窗口的数据。

要确定窗口是否处于隐身模式,检查相关的 tabs.Tab 或 windows.Window 对象的 icognito 属性。例如:

function saveTabData(tab, data) {
  if (tab.incognito) {
    chrome.runtime.getBackgroundPage(function(bgPage) {
      bgPage[tab.url] = data;      // 仅在内存中保留数据
    });
  } else {
    localStorage[tab.url] = data;  // 可以保存数据
  }
}

现在做什么呢?
现在您已经大致了解扩展程序了,您应该准备好编写您自己的扩展程序了。您接下来可以参考以下内容:


教程:调试
这一教程向您介绍如何使用 Google Chrome 浏览器内建的开发者工具来交互性地调试扩展程序。

查看扩展程序信息
要遵循这一教程,您需要入门部分的 Hello World 扩展程序。在这一部分,您将会加载扩展程序,并在扩展程序页面中查看它的信息。

如果还没运行的话请加载 Hello World 扩展程序。如果扩展程序已经运行,您将看到浏览器地址栏右边的 Hello World 图标 。

如果 Hello World 扩展程序还没有运行,请找到扩展程序文件并加载它们。如果您手边没有这些文件,从这一 ZIP 文件解压缩。如果您需要有关加载扩展程序的指导请参见入门。

进入扩展程序页面(chrome://extensions),并确保该页面处于开发者模式。
在该页面中查看 Hello World 扩展程序的信息,您可以看到一些细节,例如扩展程序的名称、描述以及标识符。
审查弹出内容
只要您的浏览器处于开发者模式中,就可以方便地审查弹出内容。

进入扩展程序页面(chrome://extensions),并确保开发者模式处于启用状态。进行以下工作时不需要扩展程序页面一直开着。即使页面没有显示,浏览器也将记住设置。
右击 Hello World 图标 ,并选择审查弹出内容菜单项。弹出内容将会出现,并且如下图所示的开发人员工具窗口将会显示 popup.html 的代码。

只要开发者工具的窗口开着,弹出内容也将一直保持打开状态。
如果 Scripts 按钮还未选中则单击它。
单击控制台按钮 (在开发者工具窗口的底部,从左边开始的第二个),这样您可以同时看到代码和控制台。
使用调试器
在这一部分,弹出页面自己添加图片时您将跟踪它的执行。

搜索 img.src,单击它出现的行号(例如,37),在添加图片的循环中设置断点。

确保您可以看到 popup.html 的内容,它应该显示 20 个 “hello world” 图片。
在控制台提示符中,输入 location.reload(true) 重新加载弹出页面:

location.reload(true)

弹出页面在重新加载时会变成空白,并且执行将在第 37 行停止。

在工具窗口的右上角,您应该能看到本地变量。这一部分显示当前作用域内所有变量的值。例如,在如下屏幕截图中 i 的值为 0,photos 是包含一些元素的节点列表。(事实上,它包含 20 个元素,索引从 0 至 19,每一个代表一张照片。)

单击开始/暂停按钮 (在开发者工具窗口的右上角),执行一次图片处理循环。您每一次单击该按钮后,i 的值就会递增,并且弹出页面中出现另一个图标。例如,当 i 为 10 时,弹出页面如下图所示:
the popup page with 10 images

使用开始/暂停旁边的按钮来进行逐过程、逐语句调试或完成函数调用。要让页面完成加载,请单击第 37 行删除断点,并按下开始/暂停按钮 继续执行。
总结
该教程演示了一些您可以用来调试扩展程序的技术:

在扩展程序页面(chrome://extensions)中找到您的扩展程序标识符以及指向其页面的链接。
使用 chrome-extension://扩展程序标识符/filename 查看较难到达的页面(以及您的扩展程序中的任何其他文件)。
使用开发者工具审查并单步调试页面的 JavaScript 代码。
在控制台中使用 location.reload(true) 重新加载当前审查的页面。
接下来做什么?
现在您已经熟悉了调试过程,如下是有关接下来做什么的建议:

观看扩展程序视频开发与调试(英文)。
尝试安装和审查其他扩展程序,例如示例。
尝试在您的扩展程序的 JavaScript 代码中使用常见的调试 API,例如 console.log() 和 console.error()。例如:console.log(“Hello, world!”)
遵循开发人员工具教程(英文),浏览开发人员工具网站(英文),并观看一些视频教程。
有关更多想法,请参见入门中的接下来做什么?部分。

猜你喜欢

转载自blog.csdn.net/yeshennet/article/details/83049354