应用程序手机分辨率
手机分辨率 时间:2021-04-01 阅读:(
)
第3章Android应用程序剖析用户要想编写出复杂的应用程序,首先要对Android应用程序的构成及程序的内部执行流程有一个清晰的了解.
本章通过对一个简单的应用程序的深入剖析,使读者对Android应用程序的构成及执行流程有个清晰的了解.
3.
1Android应用程序目录结构之前我们已经开发了一个项目名称为HelloWorld的Android应用程序,也许你很疑惑,好像什么都没做,只是输入了几个名字,点了几下鼠标,应用程序就可以运行.
这里面到底发生了什么本节将对HelloWorld程序的目录结构进行详细分析.
图3.
1所示是HelloWorld在Eclipse中的目录层次结构,下面对其中主要的目录极其文件进行介绍.
图3.
1项目目录结构项目的根下有几个重要的文件(夹),下面详细讲解每个文件夹的功能和作用.
src/——专门存放编写的java源代码的包.
android2.
1/——存放Android自身的jar包.
gen/——该目录不用开发人员维护,但又非常重要的目录,该目录用来存放由Android开发工具所生成的目录,该目录下的所有文件都不是用户创建的,而是由ADT自动生成的,该目录下的R.
java文件非常重要,后面会详细介绍.
assets/——该目录用来存放应用中用到的类似于视频文件、MP3的一些媒体文件.
res/——是resource的缩写,为资源目录,该目录可以存放一些图标、界面文件、应第3章Android应用程序剖析21用中用到的文字信息.
AndroidManifest.
xml——该文件是系Android项目的系统清单文件,它用于控制Android应用的名称、图标、访问权限等整体属性.
default.
properties——该文件一般也不需要手工去更改,文件存放了项目对应的一些环境配置,如应用要求运行的最低Android版本.
资源被编译到最终的APK文件里.
Android创建了一个被称为R的类,这样在Java代码中可以通过它关联到对应的资源文件.
接下来对res/的子目录做更加详细的说明.
(1)res/drawableres/目录下有三个dawable文件夹,区别只是将图标按分辨率高低来放入不同的目录,其中,【drawable-hdpi】用来存放高分辨率的图标,【drawable-mdpi】用来存放中等分辨率的图标,【drawable-ldpi】用来存放低分辨率的图标.
程序运行时可以根据手机分辨率的高低选取相应目录下的图标.
不过,如果不想准备过多图片,那么也可以只准备一张图标将其放入三个目录的任何一个中去.
(2)res/values文件夹①strings.
xml用来定义字符串和数值,在Activity中使用getResources().
getString(resourceId)或getResources().
getText(resourceId)取得资源.
打开helloworld项目的string.
xml,可以看到如下内容.
HelloWorldHelloworld!
Settings每个string标签声明了一个字符串,name属性指定其引用名.
为什么需要把应用中出现的文字单独放在string.
xml文件中呢原因有如下两点.
一是为了国际化,Android建议将在屏幕上显示的文字定义在strings.
xml中,如果今后需要进行国际化,如开发的应用本来是面向国内用户的,当然要在屏幕上使用中文,而如今要让应用走向世界,打入日本市场,当然需要在手机屏幕上显示日语,如果没有把文字信息定义在strings.
xml中,就需要修改程序内容了.
但当我们把所有屏幕上出现的文字信息都集中存放在strings.
xml文件之后,只需要再提供一个strings.
xml文件,把里面的汉字信息都修改为日语,再运行程序时,Android操作系统会根据用户手机的语言环境和国家来自动选择相应的strings.
xml文件,这时手机界面就会显示出日语,这样做国际化非常方便.
二是为了减少应用的体积,降低数据冗余.
假设在应用中要使用"我们一直在努力"这段文字10000次,如果不将"我们一直在努力"定义在strings.
xml文件中,而是在每次使用时直接写上这几个字,这样下来程序中将有70000个字,这70000个字占136KB的精通Android应用开发22空间.
而由于手机的资源有限,其CPU的处理能力及内存是非常有限的,136KB对手机程序来说是个不小的空间,在做手机应用时一定要记住"能省内存就省内存",而如果将这几个字定义在strings.
xml中,在每次使用到的地方通过Resources类来引用该文字,只占用了14B,对降低应用体积效果非常有效.
当然我们在开发时并不会用到这么多的文字信息,但是"不以善小而不为,不以恶小而为之",作为手机应用开发人员,一定要养成良好的编程习惯.
②styles.
xml用来定义样式.
打开本项目的style.
xml文件,内容如下.
注意:Android中的资源文件不要以数字作为文件名,这样会导致错误.
(3)res/layout目录下的布局文件本例中的布局文件是ADT默认自动创建的activity_main.
xml文件.
可以用两种方式GraphicalLayout者xml清单显示其中的内容,在Eclipse中,这两种查看方式可以随意切换.
双击打开此xml文件,内容如下.
与在网页中布局中使用HTML文件相同,Android在XML文件中使用XML元素来设定屏幕布局.
每个文件包含整个屏幕或部分屏幕,被编译进一个视图资源,可以被传递给Activity.
setContentView或被其他布局文件引用.
文件保存在工程的res/layout/目录下,它被Android资源编辑器编译.
3.
1.
1gen/目录下的R.
java文件详解R.
java文件中默认有attr、drawable、layout、string等四个静态内部类,每个静态内部类分别对应一种资源,如layout静态内部类对应layout中的界面文件,其中,每个静态内部类中的静态常量分别定义一条资源标识符,如"publicstaticfinalintactivity_main=0x7f030000;"对应的是layout目录下的activity_main.
xml文件.
具体的对应关系,如图3.
2所示.
图3.
2R.
java中的资源的对应关系图现在已经理解了R.
java文件中内容的来源,也即当开发者在res/目录中任何一个子目录中添加相应类型的文件后,ADT会在R.
java文件中相应的匿名内部类当中自动生成一条静态int类型的常量,对添加的文件进行索引.
如果在layout目录下再添加一个新的界面,那么在publicstaticfinalclasslayout中也会添加相应的静态int常量.
相反,在res目录下删除任何一个文件,其在R.
java中对应的记录会被ADT自动删除.
再比如说,在精通Android应用开发24strings.
xml添加一条记录,在R.
java的string内部类中也会自动增加一条记录.
R.
java文件会给开发程序带来很大的方便,如在程序中使用"publicstaticfinalintic_launcher=0x7f020000;"就可以找到其对应的ic_launcher图片.
R.
java文件除了有自动标识资源的"索引"功能外,还有另一个主要的功能,当res目录中的某个资源在应用中没有被使用到,在该应用被编译时系统就不会把对应的资源编译到该应用的APK包中,这样可以节省Android手机的资源.
3.
1.
2组件标识符通过对R.
java文件的介绍,读者已经了解了R文件的索引作用,它可以检索到应用中需要使用的资源.
下面介绍如何通过R.
java文件来引用到所需要的资源.
(1)在Java程序当中,可以按照Java的语法来引用.
①R.
resource_type.
resource_name注意,resource_name不需要文件的后缀名.
比如,上面的ic_launcher.
png文件的资源标识符可以通过如下方式获取.
R.
drawable.
ic_launcher②android.
R.
resource_type.
resource_nameAndroid系统本身自带了很多资源,用户也可以进行引用,只是需要在前面加上"android.
"以声明该资源来自Android系统.
(2)在XML文件中引用资源的语法如下:①@[package:]type/name,使用自己包下的资源可以省略package.
在xml文件中,如activity_main.
xml以及AndroidMainfest.
xml文件中通过"@drawable/ic_launcher"的方式获取.
其中"@"代表R.
java类,"drawable"代表R.
java中的静态内部类"drawable","/ic_launcher"代表静态内部类"drawable"中的静态属性"ic_launcher".
该属性可以指向res目录下的"drawable-*dpi"中的ic_launcher.
png图标.
其他类型的文件类似,凡是在R文件中定义的资源都可以通过"@Static_inner_classes_name/resourse_name"的方式获取.
如"@id/button","@string/app_name".
②如果访问的是Android系统中带的文件,则要添上包名"android:".
如android:textColor="@android:color/red".
(3)"@+id/string_name"表达式顺便说一下,在布局文件当中我们需要为一些组件添加Id属性作为标示,可以使用如下的表达式"@+id/string_name",其中,"+"表示在R.
java的名为id的内部类中添加一条记录.
如"@+id/button"的含义是在R.
java文件中的id这个静态内部类添加一条常量名为button,该常量就是该资源的标识符.
如果id这个静态内部类不存在,则会先生成它.
通过该方式生成的资源标识符,仍然可以以"@id/string_name"的方式引用.
示例代码片段如下.
其中,android:id="@+id/cancle"将其所在的Button标识为cancle,在第二个Button中通过"@id/cancle"对第一个Button进行引用.
3.
1.
3AndroidMainfest.
xml详细介绍每个应用程序都有一个功能清单文件AndroidManifest.
xml(一定是这个名字)在它的根目录里,该清单文件给Android系统提供了关于这个应用程序的基本信息,系统在运行任何程序代码之前必须知道这些信息.
今后,我们开发Activity、Broadcast、Service之后,都要在AndroidManifest.
xml中进行定义.
另外,如果使用到系统自带的服务如拨号服务、应用安装服务、GPRS服务等都必须在AndroidManifest.
xml中声明权限.
AndroidManifest.
xml主要包含以下功能.
命名应用程序的Java应用包,这个包名用来唯一标识应用程序.
描述应用程序的组件——活动、服务、广播接收者、内容提供者;对实现每个组件和公布其功能(比如,能处理哪些意图消息)的类进行命名,这些声明使得Android系统了解这些组件及它们在什么条件下可以被启动.
决定应用程序组件运行在哪个进程中.
声明应用程序所必须具备的权限,用以访问受保护的部分API,以及和其他应用程序交互.
声明应用程序其他的必备权限,用以组件之间的交互.
列举测试设备Instrumentation类,用来提供应用程序运行时所需的环境配置及其他信息,这些声明只在程序开发和测试阶段存在,发布前将被删除.
声明应用程序所要求的AndroidAPI的最低版本级别.
列举application所需要链接的库.
下面以HelloWorld项目的功能清单文件为例进行讲解.
精通Android应用开发26以下详细讲解各个标签.
(1)元素该元素是AndroidManifest.
xml文件的根元素,该元素为必选.
其中,根据xml文件的语法,"xmlns:android"指定该文件的命名空间.
功能清单文件会使用"http://schemas.
android.
com/apk/res/android"所指向的一个文件.
"package"属性是指定Android应用所在的包.
"android:versionCode"指定应用的版本号.
如果应用需要不断升级,在升级时应该修改该值.
"android:versionName"是版本名称,名称的取定可根据爱好而定.
(2)元素是非常重要的一个元素,今后,开发的许多组件都会在该元素下定义,该元素为必选元素.
的"icon"属性用来设定应用的图标.
的"label"属性用来设定应用的名称.
指定其属性值所用的表达式"@string/app_name"含义与上面的表达式"@drawable/ic_launcher"相同,同样指向R.
java件中的string静态内部类中的app_name属性所指向的资源.
这里它指向的是"strings.
xml"文件中的一条记录"app_name",其值为"HelloWorld",因此,这种表达方式等价于android:label="HelloWorld".
(3)元素元素的作用是注册一个Activity信息,当我们在创建"HelloWorld"这个项目时,指定了【CreateActivity】属性为"MainActivity",之后ADT在生成项目时帮我们自动创建了一个Activity名称就是"MainActivity.
java",Activity在Android中属于组件,它需要在功能清单文件中进行配置.
元素的"name"属性指定的是该Activity的类名.
元素的"label"属性表示Activity所代表的屏幕标题,其属性值的表达式在上面已经介绍过了,不再赘述.
该属性值在AVD运行程序到该Activity所代表的界面时,会在标题上显示该值.
(4)元素翻译成中文是"意图过滤器".
首先简单介绍什么是意图(Intent).
应用程序的核心组件(活动、服务和广播接收器)通过意图被激活,意图代表的是你要做的一件事情,代表你的目的,Android寻找一个合适的组件来响应这个意图,如果需要会启动这个组件一个新的实例,并传递给这个意图对象,后面会有详细介绍.
组件通过意图过滤器(intentfilters)通告它们所具备的功能——能响应的意图类型.
由于Android系统在启动一个组件前必须知道该组件能够处理哪些意图,那么意图过滤器需要在manifest中以元素指定.
一个组件可以拥有多个过滤器,每一个描述该组件所具有的不同能力.
一个指定目标组件的显式意图将会激活那个指定的组件,意图过滤器不起作用.
但是一个没有指定目标的隐式意图只在它能够通过组件过滤器时才能激活该组件.
第一个过滤器——精通Android应用开发28是最常见的,它表明这个activity将在应用程序加载器中显示,就是用户在设备上看到的可供加载的应用程序列表.
换句话说,这个activity是应用程序的入口,是用户选择运行这个应用程序后所见到的第一个activity.
(5)权限PermissionsHelloWorld项目的功能清单文件中并没有出现元素,但是Permission也是一个非常重要的节点,在后面的学习中会经常用到.
Permission是代码对设备上数据的访问限制,这个限制被引入来保护可能会被误用而曲解或破坏用户体验的关键数据和代码.
如拨号服务、短信服务等.
每个许可被一个唯一的标签所标识.
这个标签常常指出了受限的动作.
如申请发送短信服务的权限需要在功能清单文件中添加如下语句.
一个功能(feature)最多只能被一个权限许可保护.
如果一个应用程序需要访问一个需要特定权限的功能,它必须在manifest元素内使用元素来声明这一点.
这样,当应用程序安装到设备上之后,安装器可以通过检查签署应用程序认证的机构来决定是否授予请求的权限,在某些情况下,会询问用户.
如果权限已被授予,那应用程序就能够访问受保护的功能特性.
如果没有,访问将失败,但不会给用户任何通知.
因此我们在使用一些系统服务,如拨号、短信、访问互联网、访问SDCard时一定要记得添加相应的权限,否则会出现一些难以预料的错误.
应用程序还可以通过权限许可来保护它自己的组件(活动、服务、广播接收器、内容提供者).
它可以利用Android已经定义(列在android.
Manifest.
permission中)或其他应用程序已声明的权限许可,或者定义自己的许可.
一个新的许可通过元素声明.
比如,一个Activity可以用下面的方式保护.
.
.
.
.
.
.
.
.
.
第3章Android应用程序剖析29注意:在这个例子里,这个DEBIT_ACCT许可并非仅仅在元素中声明,如果该应用程序的其他组件要使用到该组件,那么它同样声明在元素里.
(6)库Libraries每个应用程序都链接到缺省的Android库,这个库包含了基础应用程序开发包(实现了基础类如活动、服务、意图、视图、按钮、应用程序、内容提供者等).
然而,一些包处于它们自己的库中.
如果你的应用程序使用了其他开发包中的代码,它必须显式地请求链接到它们.
这个manifest必须包含一个单独的元素来命名每一个库.
如在进行单元测试的时候需要引入其所需要的库.
代码片段如下:3.
2Android应用程序的执行流程经过前面对Android项目目录结构的介绍,以及相关文件的讲解,我们对许多细节已经有所了解,只是Android程序是如何执行呢下面做一个总结.
发布程序到手机上之后,当双击该应用的图标时,系统会将这个点击事件包装成一个Intent该Intent包含两个参数.
{action:"android.
intent.
action.
MAIN",category:"android.
intent.
category.
LAUNCHER"},这个意图被传递给HelloWorld这个应用之后在应用的功能清单文件中寻找与该意图匹配的意图过滤器,如果匹配成功,找到相匹配的意图过滤器所在的Activity元素,再根据元素的"name"属性来寻找其对应的Activity类.
接着Android操作系统创建该Activity类的实例对象,对象创建完成之后,会执行到该类的onCreate方法,此OnCreate方法是重写其父类Activity的OnCreate方法而实现.
onCreate方法用来初始化Activity实例对象.
如下是HelloWorld.
java类中onCreate方法的代码.
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.
onCreate(savedInstanceState);setContentView(R.
layout.
activity_main);}其中,super.
onCreate(savedInstanceState)的作用是调用其父类Activity的OnCreate方法来实现对界面的画图绘制工作.
在实现自己定义的Activity子类的OnCreate方法时一定精通Android应用开发30要记得调用该方法,以确保能够绘制界面.
setContentView(R.
layout.
main)的作用是加载一个界面,该方法中传入的参数是"R.
layout.
activity_main",其含义为R.
java类中静态内部类layout的静态常量activity_main的值,而该值是一个指向res目录下的layout子目录下activity_main文件的标识符,因此代表着显示activity_main所定义的画面.
关于Activity类的执行流程及其生命周期会在后面的部分详细讲解.
Android程序执行的整个序列图如图3.
3所示.
图3.
3Android应用执行序列图3.
3Android应用程序的基本组件在第1章中我们提到了Android平台的几大优点,其中,包括开放性和应用程序平等.
的确,Android最吸引人的特性之一就是应用程序可以利用其他应用程序来完成想要的功能!
例如,你的应用程序需要用到图片浏览功能,而这时正好有另一个应用程序已经开发出一个合适的图片浏览程序,太好了!
你再也不用自己开发图片浏览程序,而是直接利用已有的程序即可.
那么,如何才能利用别的应用程序中的成果呢只需要在必要时启动那个图片浏览功能.
这听起来简直不可思议,Android平台是如何完成这样神奇的工作呢与其他计算机平台上的应用程序不同,Android应用程序没有唯一的启动入口(如C语言中main()函数入口),一个Android应用程序是由多个不同的组件组合而成,组件之间通过Intent来实现通信.
Android系统的基本组件包括Activity、Service、BroadcastReceiver、ContentProvider等,此外,还包括专门负责在基本组件之间传递消息的Intent组件.
所有这些组件都必须第3章Android应用程序剖析31在AndroidManifest.
xml文件中声明,这些组件如何协调工作呢下面通过一个简单的用户与应用程序交互的例子来说明Android程序中上述组件是如何配合的,这里包含了两个Activity,如图3.
4所示.
图3.
4示例应用程序的结构首先,用户通过Activity与应用程序交互,如图中步骤1.
应用程序中的Activity通过Intent来向Android平台请求启动一个能处理打开Email的应用程序,如图中步骤2和步骤3.
Android系统通过AndroidManifest.
xml中声明的IntentFilter找到能处理打开Email的应用程序,如图中步骤4和步骤5.
用户与Email应用程序进行交互,如图中步骤6.
Email应用程序通过ContentProvider来使用另一个录音应用程序产生的音频文件,如图中步骤7.
用户播放刚才的音频文件,并返回到了之前的应用程序,此时音频文件仍然会继续播放,因为Service将在后台工作,如图中的步骤8.
当然,并不是每个Android应用程序都必须包含这些组件,但是一旦确定了应用程序中需要的组件,就应该在AndroidManifest.
xml中声明它们.
接下来对这些基本组件做简单地介绍,使读者对这些组件建立一个大致的认识,后面章节还会对这些组件详细介绍.
3.
3.
1ActivityActivity是应用程序的表示层.
应用程序中的每个屏幕显示都通过集成和扩展基类Activity来实现.
Activity利用View来实现应用程序的GUI,而手机用户则直接通过GUI和应用程序交互,如应用程序通过GUI向用户显示信息,用户通过GUI向应用程序发出指令和响应.
例如,一个短信应用程序,需要一个Activity来显示联系人列表,同时需要另一个精通Android应用开发32Activity显示用户输入的短信内容,甚至还可能需要第三个Activity显示已收到短信的内容.
虽然这些Activity整体形成了一个完整的短信程序用户界面,但实际上每个Activity是独立的.
当然,它们也有共同点——每个Activity都是继承自Activity的子类.
应用程序往往由多个Activity组成.
一个应用程序需要多少个Activity每个Activity表示什么样的用户界面这些问题都取决于具体的应用程序设计.
通常的原则是,程序启动后显示的第一副画面是应用程序的第一个Activity,以后根据应用程序的需要从一个Activity跳转到一个新的Activity.
下面这段代码展示了之前的项目HelloWorld创建Activity的方法.
publicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.
onCreate(savedInstanceState);setContentView(R.
layout.
activity_main);}对于每个Activity,系统会分配一个默认的窗口.
一般情况下,窗口将沾满整个屏幕.
改变默认属性,窗口大小也是可调整的.
窗口的显示位置也可以悬浮在其他窗口之上.
Activity同时也能使用别的窗口,为了提醒用户,可以在一个Activity中使用弹出对话框.
Activity窗口内的可见内容通过View提供,View对象继承自View类,每个View对象控制这窗口内的一个巨型空间.
View是一种层次结构,父View包含的布局属性会被子View继承.
位于View层次关系最底部的子View对象所代表的矩形空间就是跟用户进行交互的地方.
例如,我们可以用一个View对象来显示图片,并在用户点击图片时产生相应的动作.
Android自带了很多不同的View供开发者使用,如按钮、文本框、滚动条、菜单项等,这些内容会在后续章节进行详细介绍.
既然Activity的内容通过View来显示,那么如何才能将View对象放入Activity中呢可以调用Activity.
setContentView(),如上面代码中的最后一行.
3.
3.
2ServiceService与Activity的地位是并列的,它也代表一个单独的Android组件.
但与Activity相反,Service没有可见的界面,它的特点是能长时间在后台运行,也可以这样理解,Service是具有一段较长生命周期且没有用户界面的程序.
为什么我们需要长时间在后台运行的Service想想音乐播放器!
可能在播放音乐的同时去编辑短信或浏览网页,就像笔者现在就一边写书一边听着音乐,这种情况下音乐播放器不可能一直处于前台.
为了让音乐一直播放下去,需要将播放音乐的任务放在后台.
这样,即使音乐播放器已经不再显示了,用户仍然可以听到音乐.
所以,我们需要这样的机制——长时间在后台运行的Service.
与Activity组件需要集成Activity基类相似,Service组件需要继承Service基类.
一个Service组件被运行起来后,它将拥有自己独立的生命周期.
第3章Android应用程序剖析333.
3.
3BroadcastReceiverBroadcastReceiver是用户接受广播通知的组件.
广播是一种同时通知多个对象的事件通知机制.
Android中的广播通知要么来自系统,要么来自普通应用程序.
很多事件都可能导致系统广播,如手机所在的时区发生变化,电池电量低,用户改变系统语言设置等.
当然也有广播来自应用程序,比如,一个应用程序通知其他应用程序某些数据已经下载完毕.
为了响应不同的事件通知,应用程序可以注册不同的BroadcastReceiver,而所有的BroadcastReceiver都继承自基类BroadcastReceiver.
需要说明的是,BroadcastReceiver自身并不实现图形用户界面,但是当它收到某个通知消息后,BroadcastReceiver可以启动Activity作为响应,或者通过NotificationManager提醒用户.
3.
3.
4ContentProvider在Android中,每个应用程序都使用自己的用户id并在自己的进程中运行.
这样做的好处是,可以保护系统及应用程序,避免被其他不正常的应用程序影响,每个进程都拥有独立的进程地址空间和虚拟内存.
当应用程序彼此间需要共享资源时,这样的架构必须需要一个妥善的解决方案.
例如,Contacts应用程序内存中保存使用者的联系资料,当你在Email中要填写收信人时,希望读取Contacts内的联系人资料.
由于Contacts和Email这两个应用程序运行在不同的进程中,因此,它们无法直接通过内存共享联系人资料.
为了解决应用程序间数据通信、共享的问题,Android提供了ContentProvider机制.
ContentProvider能将应用程序特定的数据提供给另一个应用程序使用.
数据的存储方式可以是Android文件系统,也可以是SQLite数据库,或者别的合理方式.
ContentProvider继承自父类ContentProvider,并且实现了一组标准的接口,通过这组接口,其他应用程序能对数据进行读写和存储.
然而,需要使用数据的应用程序并不是直接调用这组方法,而是通过调用ContentResolver对象的方法来完成的.
ContentResolver对象可以与任意ContentProvider通信.
3.
3.
5Intent和IntentFileter严格地说,Intent并不是Android应用的组件,但是它对于Android应用的作用非常大——它是Android应用程序内不同组件之间通信的载体.
当Android运行需要连接不同的组件时,通常需要借助Intent实现.
Intent可以启动应用中另一个Activity,也可以启动一个Service组件,还可以发送一条广播消息来触发系统中的BroadcastReceiver.
也就是说,Activity、Service、BroadcastReceiver三种组件之间的通信都以Intent为载体,只是不同组件使用Intent的机制略有区别.
具体组件间如何通过Intent进行通信,后续章节会详细介绍,在此不再赘述.
精通Android应用开发343.
4本章小结本章主要对Android应用程序进行了深入剖析,首先介绍了Android应用程序的构成及程序的内部执行流程,并对一个Android应用程序所需要的基本组件功能及其作用进行简单介绍,使读者对Android应用程序的内部执行有一个清晰的认识.
TMThosting发布了今年黑色星期五的促销活动,即日起到12月6日,VPS主机最低55折起,独立服务器9折起,开设在西雅图机房。这是一家成立于2018年的国外主机商,主要提供VPS和独立服务器租用业务,数据中心包括美国西雅图和达拉斯,其中VPS基于KVM架构,都有提供免费的DDoS保护,支持选择Windows或者Linux操作系统。Budget HDD系列架构CPU内存硬盘流量系统价格单核51...
如今我们网友可能较多的会选择云服务器、VPS主机,对于虚拟主机的话可能很多人不会选择。但是我们有些外贸业务用途的建站项目还是会有选择虚拟主机的。今天看到的Stablehost 商家虚拟主机在黑五期间也有四折优惠,对于这个服务商而言不是特别的喜欢,虽然他们商家和我们熟悉的老鹰主机商有些类似,且在后来老鹰主机改版和方案后,Stablehost 商家也会跟随改版,但是性价比认为不如老鹰主机。这次黑色星期...
前几天看到网友反馈到PacificRack商家关于处理问题的工单速度慢,于是也有后台提交个工单问问,没有得到答复导致工单自动停止,不清楚商家最近在调整什么。而且看到有网友反馈到,PacificRack 商家的之前年付低价套餐全部下架,而且如果到期续费的话账单中的产品价格会涨价不少。所以,如果我们有需要续费产品的话,谨慎选择。1、特价产品下架我们看到他们的所有原来发布的特价方案均已下架。如果我们已有...
手机分辨率为你推荐
关键字关键词标签里写多少个关键词为最好www.622hh.comwww.710av.com怎么不可以看了www.bbb551.combbb是什么意思广告法中华人民共和国广告法中,有哪些广告不得发布?www.45gtv.com登录农行网银首页www.abchina.com,hao.rising.cn我的Google Chrome主页被http://hao.rising.cn//?b=64锁定了,谁有办法?175qq.com查询QQ登录地址蜘蛛机器人在《红色警戒2共和国之辉》中,对付“蜘蛛机器人”的最好武器是什么?邯郸纠风网邯郸媒体曝光电话多少恶魔兜兜狼人杀恶魔技能是什么 PANDAKILL恶魔有什
美国免费虚拟主机 华众虚拟主机管理系统 上海vps 日本软银 80vps enzu 美国主机评论 双12活动 debian源 申请个人网站 免费高速空间 环聊 广州虚拟主机 服务器论坛 wordpress中文主题 免费个人主页 空间服务器 国内空间 小夜博客 zcloud 更多