android应用_android应用开发 - CSDN
  • 手把手做安卓应用开发

    万人学习 2016-06-30 16:53:17
    安豆是一个想学Android应用开发的小白,于是它找到自己的邻居-程序员大牛-熊哥帮忙。熊哥手把手带着安豆搭建程序的开发环境,实现应用的功能,美化应用界面,让安豆终于开发出了自己的第一个安卓应用-计算器。 ...
  • Android应用开发进阶与实践

    千人学习 2019-12-02 09:35:56
    本课程是Android应用开发的进阶篇,以实践为主,学习本课程要求学习者首先掌握Java基础,Android开发基础,此课程在此基础上进一步探索,此课程不适合没有Java和Android基础的人员。
  • Android 将自己的应用改为系统应用

    万次阅读 多人点赞 2018-09-05 21:48:17
    所谓系统程序就是system/app目录中的程序,普通应用转换成系统程序后有稳定、减少...第一种:使用ADB命令将app安装在system/app目录下转载:android 将自己的应用改为系统应用这种方法的原理就是:1、把apk文件移动到

    转载请标明出处:http://blog.csdn.net/xx326664162/article/details/53406933 文章出自:薛瑄的博客

    所谓系统程序就是system/app目录中的程序,普通应用转换成系统程序后有稳定、减少内存(DATA)空间占用、恢复出厂设置后不会消失、修改系统时间、调用隐藏方法、系统关机重启、静默安装升级卸载应用等等等等优点,想知道怎么操作?接下来我们介绍三种方法。

    第一种:使用ADB命令将app安装在system/app目录下

    参考:android 将自己的应用改为系统应用

    这种方法的原理就是:

    1、把apk文件移动到system/app目录,
    2、.so文件移动到system/lib目录。
    3、修改相应的权限

    操作步骤:

    1. 将你的手机数据线,插上,把你的设备设置为允许usb调试
    2. 打开命令终端cmd
    3. 输入命令 adb shell
    4. 确定能进入系统
    这里写图片描述

    5. 输入命令 mount
    这里写图片描述

    6. 因为system默认是只读文件夹,所以根据上面的提示输入下面命令,使其变为可读写
    mount -o remount /dev/block/nandd /system (图)
    这里写图片描述

    再出输入 mount 查看system和上面的不一样了,说明正确

    这里写图片描述

    7. 输入 exit 退出android系统终端

    8. 解压你的apk文件,进入查看lib/armeabi文件夹下有没有 .so文件,如果没有这种库文件的话,直接跳到第10步,(因为有些apk文件是要调用动态链接库的,你不拷贝的话,就没有办法运行!会报错)如果有的话, 将这些*.so文件都拷贝到/system/lib文件夹下:

    命令:adb push libiReader_txtparser.so system/lib
    这里写图片描述

    9、拷贝完了之后呢,要给这些库文件添加权限,看看别的库文件权限是几

    chmod   644  xxxxx.so

    这里写图片描述

    10. 将你的apk文件拷贝进入/system/app(该文件夹里存放着所以系统级别的apk),图中我是将iReader.apk拷贝过去的

    这里写图片描述

    11. 再次进入android终端 adb shell
    12. 进入system/app文件夹 cd system/app
    13. 查看其他apk的权限 ll 能看出区别

    这里写图片描述

    14. 修改iReader.apk权限使其和其他的一样 chmod 644 iReader.apk
    这里写图片描述

    15. 搞定这些之后,重启设备 reboot
    16. 看看系统里面是不是安装好了该应用,点击一下,看是否正常运行,可以的话,再检测是否无法卸载!

    第二种:借助工具把app转为系统应用(原理和方法一一样)

    转载:安卓进阶教程:怎样把应用转换成系统程序

    RE管理器转换和LINK2SD都可以实现,任选其一即可

    使用RE管理器转换

    1、首先我们把需要转换的程序在电脑上用压缩软件打开 ,看有没有lib这个目录。如果有,再把lib目录打开,直到出现以.so结尾的文件,把文件都拖出来备用。

    这里写图片描述这里写图片描述

    2、把需要转换的应用(apk文件)连同刚拖出的.so文件(如果有),放到手机内存卡,
    3、用RE管理器复制到system目录,把权限更改如图,
    4、把更改权限后的apk文件移动到system/app目录,.so文件移动到system/lib目录。
    5、完成后重启手机,应用就转换成系统程序了。

    使用LINK2SD转换

    这里写图片描述这里写图片描述

    如果感觉以上方法麻烦,也可借助工具来操作,LINK2SD、钛备份等软件都可以把普通程序转换为系统程序,以LINK2SD为例,打开LINK2SD,找到需要软件的程序,点击,再点操作,选择转换系统应用,接着会有个确认窗口,确认后,重启手机程序就转换好了。

    第三种:使用signapk打包成系统应用

    参考:
    android之使用signapk打包成系统应用,获取系统权限
    使用platform密钥来给apk文件签名的命令
    Android安全开发之通用签名风险
    关于android:sharedUserId=”android.uid.system”这个系统级权限
    安装APK 时, 提示” 共享用户权限不完整” , 不能安装成功, 如何解决?
    https://github.com/android/platform_build/tree/master/target/product/security

    为了更好地理解下面介绍的两种方法的原理,先来学习几个概念:

    Android应用签名机制

    Android系统要求安装的应用必须用数字证书进行签名后才能安装,并且签名证书的私钥由应用开发者保存。签名证书的生成也由开发者自己生成。在应用安装时会校验包名(package name)和签名,如果系统中已经存在了一个相同的包名和签名的应用,将会用新安装的应用替换旧的;如果包名相同但是签名不同,则会安装失败。

    为什么需要数字签名?

    数字签名是防止要保护的内容被篡改,用非对称加密算法。先对要保护的内容进行消息摘要,用私钥对消息摘要进行加密,生成数字签名,将数字签名和要保护的内容一起分发出去。 内容接收者用公钥对数字签名解密得到发送者给的消息摘要A,内容接收者对接收到的内容进行用相同的消息摘要算法处理得到消息摘要B,对比A和B是否相同,来判定传送的内容是否被篡改。 正常的APK文件是个ZIP压缩文件,除了应用的可执行文件、资源文件,还包括这些可执行文件、资源文件的摘要信息,数字证书的公钥信息等。并且通过这些签名信息可以确定APP和其开发者的关系。

    进行签名需要的工具有哪些?

    对apk进行签名需要用到签名证书和签名工具。Android系统要求对APP进行签名的数字证书可以由开发者自己生成。签名工具有jarsigner和signapk。jarsigner是Java本身自带的一个工具,他也可以对jar进行签名的;而signapk是专门为了Android应用程序apk进行签名的工具。二者的区别是:jarsigner工具签名时使用的是keystore签名文件,signapk工具签名时使用的是pk8,x509.pem文件。

    签名后的文件都有哪些?

    应用签名完后在应用的META-INF目录下会有三个文件:

    CERT.RSA、CERT.SF和MANIFEST.MF。

    MANIFEST.MF中保存了所有其他文件的SHA1摘要并base64编码后的值。

    CERT.SF文件 是对MANIFEST.MF文件中的每项中的每行加上“rn”后,再次SHA1摘要并base64编码后的值(这是为了防止通过篡改文件和其在MANIFEST.MF中对应的SHA1摘要值来篡改APK,要对MANIFEST的内容再进行一次数字摘要)。

    CERT.RSA 文件:包含了签名证书的公钥信息和发布机构信息。

    对安装包的校验过程在源码的frameworks/base/core/java/android/content/pm/PackageParser.java类中可以看到

    什么是通用签名?

    搭建好Android开发环境后(使用Eclipse或Android Studio),对APK签名的默认密钥存在debug.keystore文件中。在linux和Mac上debug.keystore文件位置是在~/.android路径下,在windows目录下文件位置是C:\user\用户名.android路径下。

    除了debug.keystore外,在AOSP发布的Android源码中,还有以下几个证书是公开的,任何人都可以获取,在源码的build/target/product/security目录中:

    这里写图片描述

    这几个证书的作用:

    testkey

    Generic default key for packages that do not otherwise specify a key.

    platform

    Test key for packages that are part of the core platform.

    shared

    Test key for things that are shared in the home/contacts process.

    media

    Test key for packages that are part of the media/download system.

    verity

    Test Key for verifiedboot system imagein Android Lollipop. Sign boot.img,sign verity metadata in system.img.

    通用签名风险:

    (1)如果攻击者的应用包名与目标应用相同,又使用了相同的密钥对应用进行签名,攻击者的应用就可以替换掉目标应用;

    (2)另外目标应用的自定义权限android:protectionlevel为“signature”或者“signatureOrSystem”时,保护就形同虚设;

    (3)如果设备使用的是第三方ROM,而第三方ROM的系统也是用AOSP默认的签名,那么使用如果使用系统级签名文件签名过的应用,权限就得到了提升。

    具体的实现方法:

    第一种是需要在Android系统源码的环境下用make来编译:

    1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId=”android.uid.system”这个属性。
    2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
    3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。

    第二种:

    下面着重介绍一个这个方法:

    1. 加入android:sharedUserId=”android.uid.system”这个属性。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.jant.addview"
              android:sharedUserId="android.uid.system" >
        <application
           ...(省略若干代码)
        </application>
    
    </manifest>

    2. 使用自己的签名文件,生成apk

    3. 使用通用签名来重新给apk文件签名。

    3.1 .准备好platform.pk8、platform.x509.pem和签名工具signapk.jar(3个文件的下载地址),还有自己的apk,放在同一个文件夹下。

    3.2 在cmd下进入到该文件夹后,使用如下命令:
    这里写图片描述

    3.3 回车后我们的文件夹下已经多了一个new.apk文件了,这就将我们的应用打包成系统应用


    你也可以在github中去下载,但是下载的是SignApk.java,需要进行一些处理,如下

    1.1.进入\build\target\product\security,找到【platform.pk8】和【platform.x509.pem】系统密钥。
    1.2.进入\build\tools\signapk找到SignApk.java,运行 javac编译成SignApk.class
    1.3.执行命令java com.android.signapk.SignApk platform.x509.pem platform.pk8 input.apk output.apk

    最后解释一下原理

    首先加入android:sharedUserId=”android.uid.system”这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成android.uid.system,也就是要让程序运行在系统进程中,也就是系统应用。

    只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform key,就是上面第二个方法提到的platform.pk8和platform.x509.pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。

    这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到platform.pk8和platform.x509.pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android中的key来签名,程序在模拟器上运行OK,不过放到小米四上安装uibl,如下图,这样也是保护了系统的安全。

    这里写图片描述

    最后还说下,这个android:sharedUserId属性不只可以把apk放到系统进程中,也可以配置多个APK运行在一个进程中,这样可以共享数据,应该会很有用的。
    你在Manifest.xml里声明使用了shareuserid 或者一些特殊permission,比如你shareuserid到uid.system,就必须使用系统platform签名来签你的apk,否则是不能安装的,同理share到其他用户id或者其他process上也是得用跟那个process运行的apk一样的签名
    一般签名肯定是厂商私有的,你肯定是没办法了,除非机器烧的是开发版本(eng)

    检验app是否已经是系统应用

    查看应用的进程属性,如果是system用户组,说明已经是系统应用。

    这里写图片描述

    关注我的公众号,轻松了解和学习更多技术
    这里写图片描述

    展开全文
  • Android应用图标微技巧,8.0系统中应用图标的适配

    万次阅读 多人点赞 2018-07-17 14:04:25
    大家好,2018年的第一篇文章到的稍微有点迟,也是因为在上一个Glide系列...三星今年推出的最新旗舰机Galaxy S9已经搭载了Android 8.0系统,紧接着小米、华为、OV等国产手机厂商即将推出的新年旗舰机也会搭载Android 8.0

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/79417483

    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每个工作日都有文章更新。

    大家好,2018年的第一篇文章到的稍微有点迟,也是因为在上一个Glide系列结束之后一直还没想到什么好的新题材。

    现在已经进入了2018年,Android 8.0系统也逐渐开始普及起来了。三星今年推出的最新旗舰机Galaxy S9已经搭载了Android 8.0系统,紧接着小米、华为、OV等国产手机厂商即将推出的新年旗舰机也会搭载Android 8.0系统。因此,现在已经是时候需要让我们的应用程序对Android 8.0系统进行适配了。

    其实在去年Android 8.0系统刚推出的时候,我就仔细翻阅过Google官方的功能变更文档。变更项着实不少,但是真正需要我们去进行功能适配的地方却并不多。总结了一下,最主要需要进行适配的地方有两处:应用图标和通知栏。那么我们就分为上下两篇来分别对这两处功能适配进行讲解,先从应用图标开始。

    为什么要进行应用图标适配?

    可能有些朋友觉得困惑,应用图标这种东西从Android远古时代就已经有了,而且功能格外的简单,就是放张图片而已,这有什么好适配的呢?但实际上,在当前Android环境下,应用图标功能是极其混乱的。

    如果说要讲一讲手机应用图标的历史,其实要从苹果开始讲起。在上世纪80年代,苹果还在设计Lisa和Macintosh电脑的时候,乔布斯就是个圆角矩形的狂热支持者。当时苹果的工程师写出了一套绝妙的算法,可以在电脑上绘制出圆和椭圆,所有观看者都被震惊了,除了乔布斯,因为乔布斯觉得圆和椭圆虽然也不错,但是如果能绘制出带圆角的矩形就更好了。当时那位工程师觉得这是不可能实现的,而且也完全用不着圆角矩形,能满足基本的绘图需求就可以了。乔布斯愤怒地拉着他走了3条街,指出大街上各种应用圆角矩形的例子,最后那位工程师第二天就做出了绘制圆角矩形的功能。

    因此,在2007年一代iPhone诞生的时候,所有应用程序的图标都毫不出乎意料地使用了圆角矩形图标,即使是第三方应用也被强制要求使用圆角矩形图标,并且这一规则一直延续到了今天的iOS 11当中,如下图所示:

    相反,Android系统在设计的时候就不喜欢苹果这样的封闭与强制,而是选择了自由与开放,对应用图标的形状不做任何强制要求,开发者们可以自由进行选择:

    可以看到,在Android上,应用图标可以是方形、圆形、圆角矩形、或者是其他任意不规则图形。

    本来就是两家公司不同的设计理念,也说不上孰高孰低。但由于Android操作系统是开源的,国内一些手机厂商在定制操作系统的时候就把这一特性给改了。比如小米手机,就选择了向苹果靠拢,强制要求应用图标圆角化。如果某些应用的图标不是圆角矩形的呢?小米系统会自动给它加上一个圆角的效果,如下图所示:

    小米的这种做法看上去是向苹果学习,但实际上是相当恶心的。因为谁都可以看出来,这种自动添加的圆角矩形非常丑,因此很多公司就索性直接将应用的图标都设计成圆角矩形的,正好Android和iOS都用同一套图标还省事了。

    但是这就让Google不开心了,这不是变向强制要求开发者必须将图标设计成圆角矩形吗?于是在去年的Google I/O大会上,Google点名批评了小米的这种做法,说其违反了Android自由和开放的理念。

    除了变向强制要求应用图标圆角化,小米的这种处理方式还有一个弊端,就是如果应用图标的圆角弧度和小米系统要求的不同,那么会出现异常丑陋的效果:

    看到这样的应用图标,真的是一脸尴尬症都要犯了。就因为这两款应用图标的圆角弧度设计得大于了小米系统要求的圆角弧度,就被自动添加上了这样丑陋的白边。

    问题是已经存在了,那么应该怎么解决呢?说实话,这确实是一个长期以来都让人头疼的问题,Google多年来对此也是睁一只眼闭一只眼。终于在Android 8.0系统中,Google下定决心要好好整治一下Android应用图标的规范性了,今天我们就来学习一下。

    8.0系统的应用图标适配

    这个问题对于Google来说还是挺难解决的。因为Google一直在强调自由与开放,那么小米强制要求所有应用图标都必须圆角化也是人家的自由呀,你不准人家这么干是不是本身就违背了自由和开放的理念呢?当然我们在这里讨论这个,有点像讨论先有鸡还是先有蛋的感觉,不过Google还是想出了一套完美的解决方案。

    从Android 8.0系统开始,应用程序的图标被分为了两层:前景层和背景层。也就是说,我们在设计应用图标的时候,需要将前景和背景部分分离,前景用来展示应用图标的Logo,背景用来衬托应用图标的Logo。需要注意的是,背景层在设计的时候只允许定义颜色和纹理,但是不能定义形状。

    那么应用图标的形状由谁来定义呢?Google将这个权利就交给手机厂商了。不是有些手机厂商喜欢学习苹果的圆角图标吗?没问题,由于应用图标的设计分为了两层,手机厂商只需要在这两层之上再盖上一层mask,这个mask可以是圆角矩形、圆形或者是方形等等,视具体手机厂商而定,就可以瞬间让手机上的所有应用图标都变成相同的规范。原理示意图如下:

    可以看到,这里背景层是一张蓝色的网格图,前景层是一张Android机器人Logo图,然后盖上一层圆形的mask,最终就裁剪出了一张圆形的应用图标。

    我一定要适配吗?

    有些朋友可能会觉得这种分成两层的应用图标设计太过于麻烦,不适配可以吗?也有些朋友可能会说,自己的APP并没有做过应用图标适配,在Android 8.0手机上也照样跑得好好的。

    事实上,这个新功能Google是准备让它慢慢过渡的,而不是一次性就强推给所有的开发者。如果你的APP中的targetSdkVersion是低于26的,那么就可以不用进行应用图标适配,Android 8.0系统仍然是向下兼容的。但是如果你将targetSdkVersion指定到了26或者更高,那么Android系统就会认为你的APP已经做好了8.0系统的适配工作,当然包括了应用图标的适配。

    如果你将targetSdkVersion指定到了26,但是却没有进行Android 8.0系统的应用图标适配,那么会出现什么样的效果呢?这里我举几个反面示例:

    这是Google Pixel手机上的截图,操作系统是Android 8.0。可以看到,这两个应用的图标都非常奇怪,本来设计的都是一个圆角矩形的图标,但是却又在外面套上了一个白色的圆圈。为什么会出现这种情况呢?就是因为这两个应用都将targetSdkVersion指定到了26以上,但是却又没有做8.0系统的应用图标适配,而Pixel手机设定的mask是圆形的,所以就自动在应用图标的外层套了一个白色的圆圈。

    由此可以看出,爱奇艺和饿了么这两款应用都是没有在Pixel上进行兼容性测试的。不过考虑到它们都是只在国内市场提供服务,因此也情有可原。

    当然了,国内的Android 8.0手机很快也要开始普及了,我相信没有任何人会希望自己的APP也出现上述的效果,因此下面我们就来开始具体学习,如何进行8.0系统的应用图标适配。

    新建一个项目

    如果有人问我8.0系统应用图标适配到底难不难?这里我会回答,一点都不难。相信所有看完这篇文章的人立马就能学会,但前提是你需要有一个好的工具——Android Studio 3.0或更高版本。

    很高兴告诉大家,Android Studio 3.0中已经内置了8.0系统应用图标适配的功能,如果你已经安装了Android Studio 3.0的话,那么恭喜你,你已经成功了百分之九十了。如果你还在用老版的Android Studio,那么赶快去升级一下,然后再接着看这篇文章。

    好的,那么现在我们就用Android Studio 3.0来新建一个项目,就叫它IconTest吧。

    创建好项目之后,打开app/build.gradle文件检查一下,确保targetSdkVersion已经指定到了26或者更高,如下所示:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 26
        defaultConfig {
            applicationId "com.example.icontest"
            minSdkVersion 15
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
    }

    可以看到,这里我在创建新项目的时候默认targetSdkVersion就是26,如果你是低于26的话,说明你的Android SDK有些老了,最好还是更新一下。当然如果你懒得更新也没关系,手动把它改成26就可以了。

    接下来打开AndroidManifest.xml文件,代码如下所示:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.icontest">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    这里我们需要关注的点是android:icon这个属性,通过这个属性,我们将应用的图标指定为了mipmap目录下的ic_launcher文件。另外大家可能注意到还有一个android:roundIcon属性,这是一个只适用在Android 7.1系统上的过渡版本,很快就被8.0系统的应用图标适配所替代了,我们不用去管它。

    刚才说了,应用图标被指定为了mipmap目录下的ic_launcher文件,那么我们快去看下这个文件吧:

    这里虽然目录很多,但是相信任何只要是入了门的Android开发者都能看得懂。唯一需要我们留意的就是mipmap-anydpi-v26这个目录,这个目录表示什么意思呢?就是Android 8.0或以上系统的手机,都会使用这个目录下的ic_launcher来作为图标。

    你会发现,mipmap-anydpi-v26目录下的ic_launcher并不是一张图片,而是一个XML文件,我们打开这个文件看一下,代码如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
        <background android:drawable="@drawable/ic_launcher_background" />
        <foreground android:drawable="@drawable/ic_launcher_foreground" />
    </adaptive-icon>

    这是一个8.0系统应用图标适配的标准写法,在<adaptive-icon>标签中定义一个<background>标签用于指定图标的背景层,定义一个<foreground>标签用于指定图标的前景层。

    那么我们分别来看一下背景层和前景层分别都是些什么内容吧,首先打开ic_launcher_background文件,内容如下图所示:

    这是一个使用SVG格式绘制出来的带纹理的底图。当然如果你看不懂这里面的代码也没有关系,因为我也看不懂。SVG格式的图片都是使用AI、PS等图像编辑软件制作之后导出的,基本没有人可以手工编写SVG图片。

    当然,背景层并不是一定要用SVG格式的图片,你也可以使用普通的PNG、JPG等格式的图片,甚至是直接指定一个背景色都可以。

    看完了背景层接着我们来看前景层,打开ic_launcher_foreground文件,内容如下所示:

    类似地,这里也是使用SVG格式绘制出了一个Android机器人的Logo,并且这个机器人还是带投影效果的。当然了,前景层我们也是可以使用PNG、JPG等格式的图片的,待会儿会进行演示。

    好的,现在已经把应用图标相关部分的代码都解释完了,那么这样一个刚刚创建完成的空项目运行起来到底会是什么样的效果呢?我们跑一下看看就知道了,如下图所示:

    可以看到,这就是一个前景层盖在背景层上,然后再被圆形mask进行裁剪之后的效果。

    好的,那么现在剩下的问题就是,我们如何才能对自己的应用图标在Android 8.0系统上进行适配?

    开始适配

    看到爱奇艺的8.0系统应用图标适配工作做得这么差,我就准备拿爱奇艺来做为例子了,我们一起来帮爱奇艺的Android版做个漂亮的应用图标适配吧。

    那么很显然,根据8.0系统的应用图标设计,我们需要准备一个前景层和一个背景层才行。

    前景层也就是爱奇艺的Logo了,这里我通过Photoshop把爱奇艺的Logo图取了出来。

    由于这是一张背景透明的图片,如果直接贴到文章里面就一片白色,啥也看不见了,于是我只好在文章里贴了一张带灰色背景的图片。如果大家需要获取爱奇艺这张前景图的原图,可以点击 这里 获取。

    解决了前景层,接下来我们来看背景层。其实背景层比前景层就简单多了,一般如果没有什么特殊需求的话,背景层直接使用某种纯色就可以了。

    这里我用Photoshop吸取了一下爱奇艺原始应用图标的背景色,值是#04ca00。当然,爱奇艺的背景色并不是完全的纯色,而是有细微的颜色渐变的。不过这里我们只是举例讲解而已,就不追究这些细节了。

    那么现在前景层和背景层都准备好了,接下来我们正式开始进行8.0系统的应用图标适配。重新回到IconTest项目当中,然后按下Windows:Ctrl+Shift+A / Mac:command+shft+A 快捷键,并输入Image Asset,如下所示:

    点击回车键打开Asset Studio编辑器,在这里就可以进行应用图标适配了。

    这个Asset Studio编辑器非常简单好用,一学就会。左边是操作区域,右边是预览区域。

    先来看操作区域,第一行的Icon Type保持默认就可以了,表示同时创建兼容8.0系统以及老版本系统的应用图标。第二行的Name用于指定应用图标的名称,这里也保持默认即可。接下来的三个页签,Foreground Layer用于编辑前景层,Background Layer用于编辑背景层,Legacy用于编辑老版本系统的图标。

    再来看预览区域,这个就十分简单了,用于预览应用图标的最终效果。在预览区域中给出了可能生成的图标形状,包括圆形、圆角矩形、方形等等。注意每个预览图标中都有一个圆圈,这个圆圈叫作安全区域,必须要保证图标的前景层完全处于安全区域当中才行,否则可能会出现图标被手机厂商的mask裁剪掉的情况。

    为了让大家能够更加直观地看到操作,这里我使用一张GIF图来演示操作的过程:

    最终,Android Studio会自动帮我们生成适配8.0系统的应用图标,以及适配老版本系统的应用图标,我们甚至一行代码都不用写,一切工作就已经完成了。感兴趣的朋友可以自己到mipmap目录下面去观察一下Android Studio帮我们生成了哪些东西,这里就不带着大家一一去看了。

    最后,让我们来运行一下程序,并且和正版爱奇艺的应用图标放在一起对比一下吧:

    可以看到,做过8.0系统应用图标适配之后,效果明显要好看太多了,也希望爱奇艺的官方APP也能早日完成适配吧。

    好了,今天这篇文章就到这里,相信大家都已经轻松掌握了Android 8.0系统的应用图标适配,下篇文章会讲解Android 8.0系统的通知栏适配,感兴趣的朋友请继续阅读 Android通知栏微技巧,8.0系统中通知栏的适配

    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

    20160507110203928         20161011100137978

    展开全文
  • 注意:首次提交应用绝对不能随便删除,否则后面再提交会显示应用APP冲突,会要求走应用认领流程,那个时候就会相当麻烦啦。 1、腾讯应用宝(必须:软件著作权) 腾讯开放平台地址:http://open.qq.com 注册开发者...

    一、问题背景

    作为一名安卓开发者,不管我们还是大学生、找工作的应届生还是已经工作的码农,如果我们能把自己开发的应用发布到国内和国外Android安卓应用上线上架应用市场,这都能作为我们安卓开发的实力体现,因为应用市场对应用上线有严格的审核机制,如国外应用市场Google Play侧重应用有无广告、年龄分级制度;而国内应用市场侧重软件著作权、项目网站ICP备案、相关资质证明等。也就是说国内和国外应用市场是不允许随便编写的一个Hello World安卓项目被发布到应用市场的,因此若我们能把自己开发的应用发布到国内和国外应用市场,这都能帮助我们把应用发布的实力体现写入考研复试、工作招聘面试的简历里等。

    二、国内Android安卓应用上线上架应用市场渠道集合

    按照下述的操作步骤,博主李同学项目团队的两款应用已经在2020年2月11日~20日,过审了Google Play、百度手机助手、腾讯应用宝、阿里应用分发平台、小米应用商店、华为应用商店。
    博主李同学过审经验:

    1. Google Play只需信用卡缴纳25美元,并且你的应用APP没有病毒、捆绑软件、恶意广告等,不需要国内任何的软件著作权、ICP备案、应用资质证明,即可在Google Play上线发布应用。博主李同学在Google Play仅提交了1次过审申请,未被驳回过1次过审申请,审核5天后2个应用直接被发布到Google Play应用商店。详细的2020年安卓应用APP上线Google Play步骤可见本文最下方。
      在这里插入图片描述
    2. 百度手机助手不强求软件著作权,可以提交保证函即可发布应用!博主李同学团队的2个应用在2018年8月时,软件著作权还在审核中,博主李同学提交保证函后便在百度手机助手发布应用了,2020年3月百度手机助手依然不强求软件著作权,这点特别有益于初入茅庐的安卓应用开发者,大家都可以去试试。博主亲测百度手机助手在2~3的工作日内。
      在这里插入图片描述
    3. 腾讯应用宝必要软件著作权,并且博主李俊德团队的2个应用是教育分类的APP,还额外提供了项目网站的ICP备案截图。博主李同学在腾讯应用宝的应用发布申请持续了9天,期间因为没有第一次打开APP的《用户协议与隐私政策》知情同意提示框、没有ICP截图等被驳回了30次左右。博主亲测,只要是星期一到星期五的工作日的17:00之前,腾讯应用宝极大概率在当天邮件通知审核结果,要么次日通知。
      在这里插入图片描述
    4. 阿里应用分发平台必要软件著作权,并且博主李俊德团队的2个应用是教育分类的APP,还额外提供了项目网站的ICP备案截图。博主李同学在阿里应用分发平台的应用发布申请持续了5天,期间因为没有ICP截图等被驳回了5次。博主亲测阿里应用分发平台在2~3的工作日内。
      在这里插入图片描述
    5. 小米应用商店必要软件著作权,并且博主李俊德团队的2个应用是教育分类的APP,还额外提供了项目网站的ICP备案截图。博主李同学在小米应用商店的应用发布申请持续了8天,期间因为项目使用过多的新手操作引导蒙版导致小米后台的自动化测试APP崩溃、没有ICP截图等被驳回了30次左右,最后博主李同学在送测小米应用商店的APP里删除了其全部的新手操作引导蒙版,最终通过了小米后台的自动化测试。博主亲测,只要是星期一到星期五的工作日的19:00之前,小米应用商店极大概率在当天邮件通知审核结果,要么次日通知。
      在这里插入图片描述
    6. 华为应用商店必要软件著作权,并且博主李俊德团队的2个应用想申请华为应用绿色标记,还额外提交了详细的应用权限说明文档。博主李同学在华为应用商店的应用发布申请持续了3天,博主李同学在华为应用商店仅提交了1次过审申请,未被驳回过1次过审申请,审核3天后2个应用直接被发布到华为应用商店。
      博主认为华为应用商店容易过审是因为其被美国制裁导致其手机不可使用Google系列产品特别是GMS,而华为想打造自己的HMS,故放宽了应用审核标准。并且华为应用商店管理中心是国内应用市场最国际化的一个,基本跟Google Play对标,其包括多国语言的应用名称、应用详细介绍等,还有可设置应用将发布的国家、应用的年龄分级制度等,希望华为的HMS未来能成功!
      在这里插入图片描述

    1.国内应用市场合集

    想要把APP上架到应用市场都要先注册开发者账号才可以。这里的方法包括注册帐号和后期上架及一些需要注意的问题。注意:首次提交应用绝对不能随便删除,否则后面再提交会显示应用APP冲突,会要求走应用认领流程,那个时候就会相当麻烦啦。

    1、腾讯应用宝(必须:软件著作权)

    • 腾讯开放平台地址:http://open.qq.com
    • 注册开发者帐号地址:https://ssl.zc.qq.com/v3/index-chs.html
    • 重要提示:开发者QQ号码一旦注册不能变更,建议使用公司老板或法人的QQ号码而不是员工私人号码注册,以免遇到员工离职等情况造成不必要的麻烦。
    • 注意事项:2017年9月18日以后应用上架要提交软件著作权证明(原件扫描)或者该应用PC官网ICP备案截图+官网地址+2个以上的应用宝以外市场上线后台状态截图代替,软著后续补上。如果APP在应用宝搜索不到(不能外显),则必须提供软著+版号。

    2、360手机助手(必须:软件著作权)

    • 360开放平台地址:http://dev.360.cn
    • 注册开发者帐号地址:http://dev.360.cn
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。企业操作人要进行实名认证,要提供身份证号,银行卡号及预留的手机验证码验证。应用上架必须要提交360的保证函。
    • 注册开发者帐号方法:http://dev.360.cn/wiki
    • 应用提交方法:http://dev.360.cn/wiki/index/id/21

    3、百度手机助手/安卓市场/91助手(没有软件著作权,可以提交保证函)

    • 百度开发者平台地址:http://app.baidu.com
    • 重要提示:百度手机助手、91助手 和安卓市场是联盟平台,在百度开发平台中上传APP通过审核后,在其它两个平台也可以搜索到自己的APP。这里只需要注册一个百度开发者帐号即可。开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。应用上架必须要提交百度的保证函。
    • 注册开发者帐号方法:http://app.baidu.com/docs?id=2&frompos=401003
    • 应用提交方法:http://app.baidu.com/docs?id=5&frompos=401007

    4、小米应用商店(必须:软件著作权)

    • 小米开放平台网站:https://dev.mi.com
    • 注册开发者帐号地址:https://account.xiaomi.com/pass/register
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。企业操作人要进行实名认证,要提供身份证号,银行卡号及预留的手机验证码验证。该认证将调用“小米支付”服务,在该小米账号下绑定银行卡进行实名认证。
    • 注册开发者帐号方法:https://dev.mi.com/docs/appsmarket/distribution/account_register/
    • 应用提交方法:https://dev.mi.com/docs/appsmarket/distribution/app_submit/

    5、华为应用市场(必须:软件著作权)

    • 华为开发者联盟地址:http://developer.huawei.com/consumer/cn
    • 注册开发者帐号地址:https://hwid1.vmall.com/CAS/portal/userRegister/regbyphone.html
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。应用上架必须要提交华为的免责函。

    6、阿里应用商店/豌豆荚/PP助手(必须:软件著作权)

    • 阿里开发者平台地址:http://open.uc.cn
    • 重要提示:阿里应用分发 整合了 豌豆荚、阿里九游、PP助手、UC应用商店、神马搜索,并联合YunOS应用商店等应用分发平台,实现全流量矩阵布局。这里只需要注册一个阿里开发者帐号即可。
      注册开发者帐号地址:https://reg.taobao.com/member/reg/fill_mobile.htm
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。企业操作人要进行实名认证,用支付宝扫描二维码进行实名认证。应用上架必须要提交阿里的保证函。
    • 注册开发者帐号方法:http://aliapp.open.uc.cn/wiki/?p=35
    • 应用提交方法:http://aliapp.open.uc.cn/wiki/?p=40

    7、三星应用商店

    • 三星开发者平台地址:http://support-cn.samsung.com/App/DeveloperChina/Home/Index
    • 重要提示:全球开发者:只有当您与 Samsung Electronics Co. 有合作关系,才应选择全球开发者类型。完成卖家注册后:请联系您的三星对手方以批准三星应用商店的合作伙伴关系请求。如果无法确认您的合作关系,您必须重新注册会员资格。
    • 主题开发者: 主题开发者类型的卖家只能使用三星SDK注册应用程序,但可以将应用程序销售到所有国家/地区。
    • 中国开发者: 中国开发者类型的卖家可注册不使用三星SDK的应用程序,但只可将应用程序出售到中国。
    • 注册开发者帐号地址:https://seller.samsungapps.com/join/joinNow.as
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。法人和联系人要双手持身份证拍照,要露出双臂,照片不能用软件处理。
    • 注册开发者帐号方法:
      http://support-cn.samsung.com/App/DeveloperChina/home/list?parentid=11&newsid=38
    • 应用提交方法:(需要下载三星应用商店上传手册)
      http://support-cn.samsung.com/App/DeveloperChina/home/list?parentid=11&newsid=11

    8、OPPO应用商店(仅支持企业,个人开发者不可发布任何应用)

    • OPPO开发者联盟地址:http://open.oppomobile.com
      注册开发者帐号地址:http://open.oppomobile.com/newuser/signup
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。必须要软件著作权,没有软著则可以试着在后台补交(华为、小米、应用宝)三家中的两家后台上架截图作为辅助依据上架,碰碰运气。应用上架必须要提交OPPO的免责函。
    • 注册开发者帐号方法:http://open.oppomobile.com/doc/index?idx=0&item=39
    • 应用提交方法:http://jingyan.baidu.com/article/d169e186656065436611d897.html

    9、ViVO应用商店(仅支持企业,个人开发者不可发布任何应用)

    • ViVO开发者联盟地址:https://dev.vivo.com.cn
    • 注册开发者帐号地址:
      https://id.vivo.com.cn/?callback=http://dev.vivo.com.cn&registerSource=1&_201707171541#!/access/register
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。要记得填写联系人信息。
    • 注册开发者帐号方法:https://dev.vivo.com.cn/doc/document/info
    • 应用提交方法:https://dev.vivo.com.cn/doc/document/info?id=52

    10、联想应用商店(仅支持企业,个人开发者不可发布任何应用)

    • 联想开发者联盟地址:http://open.lenovo.com
    • 注册开发者帐号地址:https://passport.lenovo.com/wauthen2/wauth/jsp/register.jsp
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。应用上架必须要提交联想的免责函。
    • 注册开发者帐号方法:http://open.lenovo.com/developer/adp/helpData/database_detail.jsp?url=http://open.lenovo.com/sdk/zhzc/
    • 应用提交方法: http://open.lenovo.com/developer/adp/helpData/database_detail.jsp?url=http://open.lenovo.com/sdk/?p=796

    11、魅族应用商店

    • 魅族开发者联盟地址:http://open.flyme.cn
    • 注册开发者帐号地址:https://i.flyme.cn/register
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。应用上架必须要提交魅族的免责函。
    • 注册开发者帐号方法: http://open-wiki.flyme.cn/index.php?title=%E6%96%B0%E6%89%8B%E6%8C%87%E5%8D%97
    • 应用提交方法: http://open-wiki.flyme.cn/index.php?title=%E5%BA%94%E7%94%A8%E5%8F%91%E5%B8%83

    12、金立应用商店(仅支持企业,个人开发者不可发布任何应用)

    • 金立开发者联盟地址:https://open.appgionee.com
    • 注册开发者帐号地址:https://open.appgionee.com/cp/register
    • 重要提示:开发者帐号,建议使用公司老板或法人的邮箱或手机,而不是员工私人邮箱或手机注册,以免遇到员工离职等情况造成不必要的麻烦。应用上架必须要提交金立的承诺书。
    • 注册开发者帐号方法: https://open.appgionee.com/cp/help
    • 应用提交方法: https://open.appgionee.com/cp/help

    这些都是主流的应用市场,操作流程其实在各自开发者平台官网上都可以找到,还有需要注意的是,不同类型的APP在不同应用市场需要提供的证书都会有所不同,需要上传前留意下具体需要哪些证明材料,特别是软件著作权证明或免责函。感觉华为、小米对资料的要求是最严格的;然后是360、魅族、阿里,如果你的应用程序是批量制作的,使用单一或几个模板生成的,或用简单文字、图片打包而成的话,它可以检测出来,并且不会让你通过审核。联想和vivo应该算是最好通过的。百度、小米、华为、魅族的开发者帐号审核相对慢一点,阿里、360跟腾讯还算比较快的,上架应用审核时间也相对比较快。只要资料全,其实很容易通过的。应用审核,OPPO要求要软著,审核上架不易。

    2.最新APP各应用商店上架指南

    国内目前流量逐渐中心化,而一些还不错的小市场逐渐被各种收购,更加造成了目前这种流量集中的情况。
    所以在这种情况下,就没必要花费太多精力上n个市场。一般来讲的话,应用发到百度、小米、vivo、360、应用宝、华为、oppo、魅族、pp助手、豌豆荚这几个市场就可以了。
    卓易、柠檬还有金立也还有些流量,但这几个都是要付费推广才可以上架。

    首先你要注册各大应用商店的开发者账户,注册公司主体的需要一个邮箱、一个qq号、一个手机号、营业执照、税务登记证、组织机构代码(三证合一的只需要营业执照)、企业法人身份证正反面、法人手持身份证照片。
    然后你要准备icon、市场截图、各个不同渠道名的包、市场说明、新版本说明、一句话介绍、应用关键词标签、软著权等各种资质。

    一般来讲,应用都要申请软著权,没有软著权也可以上线百度手机应用市场,但是不能加官,不能申请首发之类的。
    所以一般可以申请软著权的还是申请一个。一般找渠道的话,10个工作日内办完2200,5个工作日3000。博主李同学团队的2个项目APP应用的软件著作权是由大连理工大学和Google提供的项目经费申请的,白嫖2份的软件著作权。
    除此之外,一些应用还会有一些其他的资质要求。比如影视类应用需要《信息网络传播视听节目许可证》,小说类的需要《中华人民共和国出版物经营许可证》。
    一般市场所需其他资质如下:
    1、影音娱乐:
    视频播放器、音乐播放器及电台需要《计算机软件著作权证书》,网络直播及美女主播需要《信息网络传播视听节目许可证》或《网络视听许可证》或《节目制作经营许可证》等相关资质证件。
    2、新闻阅读:
    《计算机软件著作权证书》或《互联网新闻信息服务许可证》等企业相关经营许可资质。
    3、金融理财:
    涉及金融产品支付、银行、网贷需要《支付业务许可证》或《金融许可证》或《融资性担保机构经营许可证》或者《资金托管协议》+授权方《支付业务许可证》。
    涉及证券、期货、基金需要《中华人民共和国经营证券业务许可证》或《经营期货业务许可证》或《中华人民共和国基金销售业务资格证书》等相关业务许可证书或者《营业执照》(经营范围标明有相关业务许可的)。
    涉及彩票需要《彩票中心授权书》+《计算机软件著作权证书》。
    涉及金融理财资讯需要《营业执照》(经营范围标明金融信息咨询、证券咨询等相关信息)。
    涉及贵金属类需要《计算机软件著作权证书》+《贵金属交易相关授权资质》。
    4、医疗健康:
    涉及支付、医生问诊的应用需提供《互联网医疗保健信息服务审核同意书》或《中华人民共和国互联网药品信息服务资格证书》等相关医疗执业许可证书。
    5、学习办公:
    有支付项,提供《计算机软件著作权证书》。
    6、社交通讯:
    涉及支付、同城交友、网络电话、网赚、红包需提供《计算机软件著作权证书》。
    然后发布到各个市场,等审核就可以了,一般1~5天应用就会上线。
    备注:vivo平台的话应用内图标要为hdpi文件夹图标需变更为192x192,xhdpi文件夹图标需变更为256x256,xxhdpi文件夹图标需变更为384x384,xxxhdpi文件夹图标需变更为512x512。

    三、国外Android安卓应用上线上架应用市场渠道集合

    1.国外应用市场Google Play

    除了中国外的全世界国家的应用市场都特别的统一,仅有Google Play一家独大。不像中国,至少有十多个的应用市场需要我们开发者注册登录来发布应用,流程特别的繁琐。因此如果你想把你开发的应用发布到国外应用市场,那么就只考虑Google Play即可,只要APP发布地区把全球国家全选并且应用发布成功,那么你的应用是可以在149国家的Google Play搜索到你的应用。

    2.国外应用市场Google Play应用发布流程

    2.1Google Play发布应用的前提条件

    1. 作为发布者的你必须具备特殊的访问Google的能力。
    2. 申请一个Google Play 开发者账号需要支付25美元注册费用的信用卡,信用卡需要支持Visa, Master Amex, Discover, JCB。

    中国内网是无法访问Google相关网站的,因此想在Google Play发布应用必须具备特殊的访问Google的能力。
    博主李同学使用了大连理工大学本校的VISA信用卡完成支付,注意仅支持银联UnionPay的普通信用卡或储蓄卡是无法完成Google Play注册费用支付的。如果你没有支持Visa, Master Amex, Discover, JCB的信用卡,淘宝貌似也可以代理付费,但淘宝店铺会收取高额的手续费。
    在这里插入图片描述

    2.2注册并登录Google Play Console开发者平台

    访问Google Play Console开发者平台,若你没有Google账号就在此同时注册Google账号。
    在这里插入图片描述
    注册并登录Google账号后,因为这是你第一次访问Google Play Console开发者平台,其界面如下:
    在这里插入图片描述
    由上图Google Play Console的流程示意图,我们已经完成了Google账号登录,现在需要接收开发者协议,即在左下方打勾我同意并将愿意将我的帐户注册与Google Play开发者分发协议相关联,并确认我已经年满18岁。,并点击继续付款
    接着填入我们的信用卡信息,完成支付:
    在这里插入图片描述
    完成支付后,我们还需填写我们账户的详细信息:

    在这里插入图片描述
    终于,我们进入了Google Play Console管理中心啦!
    在这里插入图片描述

    2.3创建并发布应用

    我们进入了Google Play Console管理中心后,点击右上角的创建应用来发布我们新的应用
    在这里插入图片描述

    2.3.1填写APP的默认语言和应用名称

    填写应用的默认语言和应用名称:在这里插入图片描述
    注意:这个语言如果你选择了中文,那么里面填写APP简介和详细描述内容的时候就只能使用中文,所以这里最好选择英语,毕竟你的APP在Google Play上线肯定主要是给外国友人用的了,国内用户谁会去用Google Play。

    2.3.2填写APP的商品详情

    默认左边导航栏会选中商店发布-商品详情,我们可以先填写App的简介和详细说明:
    在这里插入图片描述
    上传屏幕截图、高分辨率图标、置顶大图。(这3项是必传内容,做为一只猿类生物,我们只需要把这个截图给UI美工看就好了,UI美工准备好图我们直接上传即可,但博主李同学是全栈工程师,全部自己一个人弄)。
    在这里插入图片描述
    接着选择APP类型和类别,填写个人或公司官网和联系邮箱(这个邮箱地址会同你的APP一起展示给用户,所以这个邮件地址不要乱填),内容分级暂时先不管,因为需要上传完apk文件才可以进行分级判断~
    在这里插入图片描述
    同理这个电话也是用户联系开发者个人或公司的渠道,隐私权政策具体规则可以点击查看用户数据政策,举个例子假如你的APP中需要查看用户的联系人信息,那么你需要说明你这个行为的原因,并且保证不会泄露用户的数据。

    这样我们商品详情的信息就都填写完毕了,点击保存草稿。

    2.3.2填写APP的应用版本

    应用版本页面有3块内容,分为正式版、Beta版、Alpha版本。正式的App建议在内测阶段先上传Alpha和Beta版本,因为Google可以提供免费的云测。这里我们直接点击管理正式版本,接着点击创建版本:
    在这里插入图片描述
    选择加入Google Play App Signing其实就是:通过Google Play的应用程序签名,Google会为您管理和保护您应用的签名密钥,并使用它来签署您的APK以进行分发。这是一种存储应用程序签名密钥的安全方式,可在您的密钥丢失或受损时帮助保护您。

    这里点击继续或者退出计划,都不会影响你的上架。(我这里点击的是加入)
    在这里插入图片描述
    点击浏览文件,上传你的apk安装包:
    在这里插入图片描述
    上传完毕后,版本号和版本名称就自动录入到填写内容中了,然后你需要填写的是“此版本中有哪些新功能”,这也没什么可说的,现在就可以去填写内容分级了。点击左边导航栏的“内容分级”:
    在这里插入图片描述

    2.3.3填写APP的内容分级

    默认左边导航栏会选中商店发布-内容分级,点击开始填写新的调查问卷
    在这里插入图片描述
    在这里插入图片描述
    填写电子邮件地址,这个邮件地址用来接收Google Play发送的消息,例如你的APP已经通过审核了的消息。然后选择你的应用类别,点击对应应用类别后会进入调查问卷页:
    在这里插入图片描述
    然后就是一系列的单选,基本上都选择否。全部选择完毕后点击保存调查问卷,再点击判断分级:
    在这里插入图片描述
    点击确认分级,内容分级项就全部完成了。

    2.3.4填写APP的定价和分发范围

    到现在为止我们就还差最后一个“定价和分发范围”了,还是在左边导航栏选择商店发布-定价和分发范围
    这一页的内容都比较好填写,主要注意一下“国家/地区”默认是0个,需要我们选择供应的国家和地区。
    在这里插入图片描述
    下图的内容准则和美国出口法律是必须要选中的,最后我们保存草稿。
    在这里插入图片描述
    如果所有内容都填写正确,我们会看到左边导航栏4个绿色对勾,并且出现“可以发布”按钮。

    2.3.5发布应用

    最后我们点击左边导航栏中的应用版本
    在这里插入图片描述
    在正式版内容项下面点击修改版本:
    在这里插入图片描述
    拉到页面左下方,点击查看按钮:
    在这里插入图片描述
    好了,到此为止你只要再点击开始发布正式版,就可以发布了。在这里插入图片描述
    再之后就是等待的过程了,Google Play官方承诺的应用审核时间是7天之内甚至更长,快的1个小时左右可以通过审核。博主李同学的应用是等待了5天才通过审核,不过比起被腾讯、小米、阿里打回应用审核20-30次,Google Play超级良心地让博主李同学申请发布应用一次通过了!

    参考文献:
    [1]简书-Google Play 上架的那些坑
    [2]Google Play 应用上架流程(有图有真相)
    [3]能上架App的GooglePlay开发者账号获取流程
    [4]安卓应用在各大应用市场上架方法整理

    展开全文
  • Android - Activity 启动过程 概述 从点击桌面应用图标到应用显示的过程我们再熟悉不过了,下面我们来分析下这个过程都做了什么。 本文主要对以下问题分析: ActivityThread 是什么,它是一个线程吗,如何被...

    Android - Activity 启动过程

    相关系列

    概述

    从点击桌面应用图标到应用显示的过程我们再熟悉不过了,下面我们来分析下这个过程都做了什么。

    本文主要对以下问题分析:

    • ActivityThread 是什么,它是一个线程吗,如何被启动的?
    • ActivityClientRecord 与 ActivityRecord 是什么?
    • Context 是什么,ContextImpl,ContextWapper 是什么?
    • Instrumentation 是什么?
    • Application 是什么,什么时候创建的,每个应用程序有几个 Application?
    • 点击 Launcher 启动 Activity 和应用内部启动 Activity 的区别?
    • Activity 启动过程,onCreate(),onResume() 回调时机及具体作用?

    Launcher

    如不了解 Android 是如何从开机到 Launcher 启动的过程,请先阅读Android - 系统启动过程

    这里写图片描述

    我们知道 Android 系统启动后已经启动了 Zygote,ServiceManager,SystemServer 等系统进程;ServiceManager 进程中完成了 Binder 初始化;SystemServer 进程中 ActivityManagerService,WindowManagerService,PackageManagerService 等系统服务在 ServiceManager 中已经注册;最后启动了 Launcher 桌面应用。

    其实 Launcher 本身就是一个应用程序,运行在自己的进程中,我们看到的桌面就是 Launcher 中的一个 Activity。

    应用安装的时候,通过 PackageManagerService 解析 apk 的 AndroidManifest.xml 文件,提取出这个 apk 的信息写入到 packages.xml 文件中,这些信息包括:权限、应用包名、icon、apk 的安装位置、版本、userID 等等。packages.xml 文件位于系统目录下/data/system/packages.xml。

    同时桌面 Launcher 会为安装过的应用生成不同的应用入口,对应桌面上的应用图标,下面分析点击应用图标的到应用启动的过程。

    点击 Launcher 中应用图标

    这里写图片描述

    点击 Launcher 中应用图标将会执行以下方法

    Launcher.startActivitySafely()
    Launcher.startActivity()
    //以上两个方法主要是检查将要打开的 Activity 是否存在
    
    Activity.startActivity()
    //这段代码大家已经很熟悉,经常打开 Activity 用的就是这个方法
    
    Activity.startActivityForResult()
    //默认 requestCode = -1,也可通过调用 startActivityForResult() 传入 requestCode。 
    //然后通过 MainThread 获取到 ApplicationThread 传入下面方法。
    
    Instrumentation.execStartActivity()
    //通过 ActivityManagerNative.getDefault() 获取到 ActivityManagerService 的代理为进程通讯作准备。
    
    ActivityManagerNative.getDefault().startActivity()
    ActivityManagerProxy.startActivity()
    //调用代理对象的 startActivity() 方法,发送 START_ACTIVITY_TRANSACTION 命令。
    

    在 system_server 进程中的服务端 ActivityManagerService 收到 START_ACTIVITY_TRANSACTION 命令后进行处理,调用 startActivity() 方法。

    ActivityManagerService.startActivity() -> startActivityAsUser(intent, requestCode, userId)
    //通过 UserHandle.getCallingUserId() 获取到 userId 并调用 startActivityAsUser() 方法。
    
    ActivityStackSupervisor.startActivityMayWait() -> resolveActivity()
    //通过 intent 创建新的 intent 对象,即使之前 intent 被修改也不受影响。 然后调用 resolveActivity()。
    //然后通过层层调用获取到 ApplicationPackageManager 对象。
    
    PackageManagerService.resolveIntent() -> queryIntentActivities()
    //获取 intent 所指向的 Activity 信息,并保存到 Intent 对象。
    
    PackageManagerService.chooseBestActivity()
    //当存在多个满足条件的 Activity 则会弹框让用户来选择。
    
    ActivityStackSupervisor.startActivityLocked()
    //获取到调用者的进程信息。 通过 Intent.FLAG_ACTIVITY_FORWARD_RESULT 判断是否需要进行 startActivityForResult 处理。 
    //检查调用者是否有权限来调用指定的 Activity。 
    //创建 ActivityRecord 对象,并检查是否运行 App 切换。
    
    ActivityStackSupervisor.startActivityUncheckedLocked() -> startActivityLocked()
    //进行对 launchMode 的处理[可参考 Activity 启动模式],创建 Task 等操作。
    //启动 Activity 所在进程,已存在则直接 onResume(),不存在则创建 Activity 并处理是否触发 onNewIntent()。
    
    ActivityStack.resumeTopActivityInnerLocked()
    //找到 resume 状态的 Activity,执行 startPausingLocked() 暂停该 Activity,同时暂停所有处于后台栈的 Activity,找不到 resume 状态的 Activity 则回桌面。
    //如果需要启动的 Activity 进程已存在,直接设置 Activity 状态为 resumed。 调用下面方法。
    
    ActivityStackSupervisor.startSpecificActivityLocked()
    //进程存在调用 realStartActivityLocked() 启动 Activity,进程不存在则调用下面方法。
    

    fork 新进程

    从 Launcher 点击图标,如果应用没有启动过,则会 fork 一个新进程。创建新进程的时候,ActivityManagerService 会保存一个 ProcessRecord 信息,Activity 应用程序中的AndroidManifest.xml 配置文件中,我们没有指定 Application 标签的 process 属性,系统就会默认使用 package 的名称。每一个应用程序都有自己的 uid,因此,这里 uid + process 的组合就可以为每一个应用程序创建一个 ProcessRecord。每次在新建新进程前的时候会先判断这个 ProcessRecord 是否已存在,如果已经存在就不会新建进程了,这就属于应用内打开 Activity 的过程了。

    ActivityManagerService.startProcessLocked()
    //进程不存在请求 Zygote 创建新进程。 创建成功后切换到新进程。
    

    进程创建成功切换至 App 进程,进入 app 进程后将 ActivityThread 类加载到新进程,并调用 ActivityThread.main() 方法

    ActivityThread.main()
    //创建主线程的 Looper 对象,创建 ActivityThread 对象,ActivityThread.attach() 建立 Binder 通道,开启 Looper.loop() 消息循环。
    
    ActivityThread.attach()
    //开启虚拟机各项功能,创建 ActivityManagerProxy 对象,调用基于 IActivityManager 接口的 Binder 通道 ActivityManagerProxy.attachApplication()。
    
    ActivityManagerProxy.attachApplication()
    //发送 ATTACH_APPLICATION_TRANSACTION 命令
    

    此时只创建了应用程序的 ActivityThread 和 ApplicationThread,和开启了 Handler 消息循环机制,其他的都还未创建, ActivityThread.attach(false) 又会最终到 ActivityMangerService 的 attachApplication,这个工程其实是将本地的 ApplicationThread 传递到 ActivityMangerService。然后 ActivityMangerService 就可以通过 ApplicationThread 的代理 ApplicationThreadProxy 来调用应用程序 ApplicationThread.bindApplication,通知应用程序的 ApplicationThread 已和 ActivityMangerService 绑定,可以不借助其他进程帮助直接通信了。此时 Launcher 的任务也算是完成了。

    在 system_server 进程中的服务端 ActivityManagerService 收到 ATTACH_APPLICATION_TRANSACTION 命令后进行处理,调用 attachApplication()。

    ActivityMangerService.attachApplication() -> attachApplicationLocked()
    //首先会获取到进程信息 ProcessRecord。 绑定死亡通知,移除进程启动超时消息。 获取到应用 ApplicationInfo 并绑定应用 IApplicationThread.bindApplication(appInfo)。
    //然后检查 App 所需组件。
    
    • Activity: 检查最顶层可见的 Activity 是否等待在该进程中运行,调用 ActivityStackSupervisor.attachApplicationLocked()。
    • Service:寻找所有需要在该进程中运行的服务,调用 ActiveServices.attachApplicationLocked()。
    • Broadcast:检查是否在这个进程中有下一个广播接收者,调用 sendPendingBroadcastsLocked()。

    此处讨论 Activity 的启动过程,只讨论 ActivityStackSupervisor.attachApplicationLocked() 方法。

    ActivityStackSupervisor.attachApplicationLocked() -> realStartActivityLocked()
    //将该进程设置为前台进程 PROCESS_STATE_TOP,调用 ApplicationThreadProxy.scheduleLaunchActivity()。
    
    ApplicationThreadProxy.scheduleLaunchActivity()
    //发送 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令
    

    发送送完 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令,还会发送 BIND_APPLICATION_TRANSACTION 命令来创建 Application。

    ApplicationThreadProxy.bindApplication()
    //发送 BIND_APPLICATION_TRANSACTION 命令
    

    App 进程初始化

    在 app 进程中,收到 BIND_APPLICATION_TRANSACTION 命令后调用 ActivityThread.bindApplication()。

    ActivityThread.bindApplication()
    //缓存 Service,初始化 AppBindData,发送消息 H.BIND_APPLICATION。
    

    ApplicationThreadProxy.bindApplication(…) 会传来这个应用的一些信息,如ApplicationInfo,Configuration 等,在 ApplicationThread.bindApplication 里会待信息封装成A ppBindData,通过

    sendMessage(H.BIND_APPLICATION, data)
    

    将信息放到应用里的消息队列里,通过 Handler 消息机制,在 ActivityThread.handleMeaasge 里处理 H.BIND_APPLICATION 的信息,调用 AplicationThread.handleBindApplication。

    handleBindApplication(AppBindData data) {
        Process.setArgV0(data.processName);//设置进程名
        ...
        //初始化 mInstrumentation
        if(data.mInstrumentation!=null) {
            mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } else {
            mInstrumentation = new Instrumentation();
        }
        //创建Application,data.info 是个 LoadedApk 对象。
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
        //调用 Application 的 onCreate()方法。
        mInstrumentation.callApplicationOnCreate(app);
    }
    
    public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
        
        if (mApplication != null) {   
           return mApplication;
        }
        
        String appClass = mApplicationInfo.className;
        java.lang.ClassLoader cl = getClassLoader();
        
        //此时新建一个 Application 的 ContextImpl 对象,
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        
        //通过在 handleBindApplication 创建的 mInstrumentation 对象新建一个 Application 对象,同时进行 attach。
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
        appContext.setOuterContext(app);
    }
    
    //设置进程名,获取 LoadedApk 对象,创建 ContextImpl 上下文
    //LoadedApk.makeApplication() 创建 Application 对象,调用 Application.onCreate() 方法。
    

    Instrumentation:

    public Application newApplication(ClassLoader cl, String className, Context context) {    
        return newApplication(cl.loadClass(className), context);
    }
    Instrumentation类:
    static public Application newApplication(Class<?> clazz, Context context)  {
        //实例化 Application
        Application app = (Application)clazz.newInstance();     
        
        // Application 和 context绑定
        app.attach(context);    
        return app;
    }
    //attach 就是将新建的 ContextImpl 赋值到 mBase,这个 ContextImpl 对象就是所有Application 内 Context 的具体实现,同时赋值一些其他的信息如 mLoadedApk。
    final void attach(Context context) {    
        mBase = base;  
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
    

    这时 Application 就创建好了,这点很重要,很多资料里说 Application 是在performLaunchActivity() 里创建的,因为 performLaunchActivity() 也有mInstrumentation.newApplication 这个调用,newApplication() 函数中可看出会先判断是否以及创建了 Application,如果之前已经创建,就返回已创建的 Application 对象。

    Activity 启动

    上面 fork 进程时会发送 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令,在 app 进程中,收到 SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION 命令后调用 ApplicationThread.scheduleLaunchActivity()。

    ApplicationThread.scheduleLaunchActivity()
    //发送消息 H.LAUNCH_ACTIVITY。
    
    sendMessage(H.LAUNCH_ACTIVITY, r);
    
    ActivityThread.handleLaunchActivity()
    //最终回调目标 Activity 的 onConfigurationChanged(),初始化 WindowManagerService。
    //调用 ActivityThread.performLaunchActivity()
    
    ActivityThread.performLaunchActivity() {
        //类似 Application 的创建过程,通过 classLoader 加载到 activity.
        activity = mInstrumentation.newActivity(classLoader, 
                   component.getClassName(), r.intent);
        //因为 Activity 有界面,所以其 Context 是 ContextThemeWrapper 类型,但实现类仍是ContextImpl.
        Context appContext = createBaseContextForActivity(r, activity);
        activity.attach(context,mInstrumentation,application,...);
        //与 Window 进行关联
        
        //attach 后调用 activity 的 onCreate()方法。
        mInstrumentation.callActivityOnCreate(activity,...)
        
    }
    //在ActivityThread.handleLaunchActivity里,接着调用
    
    Activity.performCreate() -> onCreate()
    //最终回调目标 Activity 的 onCreate()。
    
    Activity.setContentView()
    //设置 layout 布局
    
    ActivityThread.performResumeActivity()
    //最终回调目标 Activity 的 onResume()。
    
    

    与 Window 进行关联,具体过程详见:Activity,Window,View 之间的关系

    总结

    Activity 的整体启动流程如图所示:

    这里写图片描述

    • ActivityThread 是什么,它是一个线程吗,如何被启动的?

    它不是一个线程,它是运行在 App 进程中的主线程中的一个方法中。当 App 进程创建时会执行 ActivityThread.main(),ActivityThread.main() 首先会创建 Looper 执行 Looper.prepareMainLooper();然后创建 ActivityThread 并调用 ActivityThread.attach() 方法告诉 ActivityManagerService 我们创建了一个应用 并将 ApplicationThread 传给 ActivityManagerService;最后调用 Looper.loop()。

    • ActivityClientRecord 与 ActivityRecord 是什么?

    记录 Activity 相关信息,比如:Window,configuration,ActivityInfo 等。
    ActivityClientRecord 是客户端的,ActivityRecord 是 ActivityManagerService 服务端的。

    • Context 是什么,ContextImpl,ContextWapper 是什么?

    Context 定义了 App 进程的相关环境,Context 是一个接口,ContextImpl 是子类,ContextWapper 是具体实现。

    应用资源是在 Application 初始化的时候,也就是创建 Application,ContextImpl 的时候,ContextImpl 就包含这个路径,主要就是对就是 ResourcesManager 这个单例的引用。

    可以看出每次创建 Application 和 Acitvity 以及 Service 时就会有一个 ContextImpl 实例,ContentProvider 和B roadcastReceiver 的 Context 是其他地方传入的。

    所以 Context 数量 = Application 数量 + Activity 数量 + Service 数量,单进程情况下 Application 数量就是 1。

    • Instrumentation 是什么?

    管理着组件Application,Activity,Service等的创建,生命周期调用。

    • Application 是什么,什么时候创建的,每个应用程序有几个 Application?

    Application 是在 ActivityThread.handleBindApplication() 中创建的,一个进程只会创建一个 Application,但是一个应用如果有多个进程就会创建多个 Application 对象。

    • 点击 Launcher 启动 Activity 和应用内部启动 Activity 的区别?

    点击 Launcher 时会创建一个新进程来开启 Activity,而应用内打开 Activity,如果 Activity 不指定新进程,将在原来进程打开,是否开启新进程实在 ActivityManagerService 进行控制的,上面分析得到,每次开启新进程时会保存进程信息,默认为 应用包名 + 应用UID,打开 Activity 时会检查请求方的信息来判断是否需要新开进程。Launcher 打开 Activity 默认 ACTIVITY_NEW_TASK,新开一个 Activity 栈来保存 Activity 的信息。

    • Activity 启动过程,onCreate(),onResume() 回调时机及具体作用?

    Activity.onCreate() 完成了 App 进程,Application,Activity 的创建,调用 setContentView() 给 Activity 设置了 layout 布局。

    Activity.onResume() 完成了 Activity 中 Window 与 WindowManager 的关联,并对所有子 View 进行渲染并显示。

    参考资料

    其他系列

    Gradle 系列

    更多文章:

    这是我博客长期更新的项目,欢迎大家 Star。
    https://github.com/jeanboydev/Android-ReadTheFuckingSourceCode

    我的公众号

    欢迎你「扫一扫」下面的二维码,关注我的公众号,可以接受最新的文章推送,有丰厚的抽奖活动和福利等着你哦!?

    qrcode_android_besos_black_512.png

    如果你有什么疑问或者问题,可以 点击这里 提交 issue,也可以发邮件给我 jeanboy@foxmail.com

    同时欢迎你 Android技术进阶:386463747 来一起交流学习,群里有很多大牛和学习资料,相信一定能帮助到你!

    展开全文
  • 安卓 Android之开发简单小应用(一)

    万次阅读 多人点赞 2018-10-30 11:29:32
    安卓 Android之开发简单小应用(一) 一、简述  记 --没学过Android之开发简单小应用。(课程设计作业)  例子打包:链接:https://pan.baidu.com/s/1LEQ1oWkUX8OmtfCFVydxWQ 密码:9o0d 二、环境搭建 软件打包:...
  • \Android应用开发

    2020-07-13 23:31:20
    \Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android应用开发\Android...
  • 课程目录酷蜂科技-Android应用开发视频教程-1.1_android学习路线图_1酷蜂科技-Android应用开发视频教程-1.2_android搭建开发环境_1酷蜂科技-Android应用开发视频教程-1.3_android目录结构介绍_1酷蜂科技-Android应用...
  • Android Web应用 Android 开发管家技术与精彩案例 Android 开发实战经典 Android 平台开发之旅 Android 开发应用实战详解 Android 经典应用程序开发 Android 开发应用从入门到精通 ...
  • Android 开发管家技术与精彩案例 Android 开发实战经典 ...Android 平台开发之旅 ...Android 开发应用实战详解 Android 经典应用程序开发 Android 开发应用从入门到精通 Android 从入门到精通 An
  • 使用的是activity-alias来动态更换应用的图标和应用名称
  • Android 图书总汇

    千次阅读 2011-12-28 23:26:08
    Android 图书总汇 共有58本书 Google Android SDK开发范例大全(第3版) Google Android手机游戏设计达人讲座 Android江湖 智能手机跨平台开发高级教程—适用于...
  • Android应用程序开发教程Android Studio版》
  • Android开发---打开外部应用

    千次阅读 2018-10-12 20:17:17
    Android应用打开另一个应用程序 Android app中调用启动其他应用(系统应用和第三方应用)2016.10.25新增android 6.0打电话api Android调用另一个App界面 Android中通过外部程序启动App的三种方法 ...
  • 通过Android studio获取应用签名

    千次阅读 2019-03-18 16:23:23
    Android studio底部的控制台输入: keytool -list -v -keystore "路径\签名文件名.jks" 然后输入密码即可获取签名的MD5和SHA1值。
  • 很不错的资源,Android入门及提升有很大的帮助
  • Android应用开发详解

    2020-07-30 23:30:30
    Android应用开发详解》 作者:郭宏志 编著 内容简介 本书分为三个部分,包括基础篇、技术篇和应用篇。由浅入深地讲述了Android应用开发的方方面面。 第一篇 基础篇 第1章 Android概述 Android概述,讲述了...
  • android标签概述

    千次阅读 2015-02-25 16:41:34
    android:allowTaskReparenting:是否应用中的activity是否能从启动时的task移动到task android:allowbackup:应用备份 android:backupAgent:备份代理类名 android:banner:广告条,比如用于AndroidTV主屏上 android...
  • 首页 | Android初级 | Android资料 |Android进阶 |Android源码 |Android书籍 |Android游戏开发 ...Android基于Linux,开发者可以使用Java或C/C++开发Android应用。本专题将为大家详解Andr
1 2 3 4 5 ... 20
收藏数 2,265,740
精华内容 906,296
关键字:

android应用