简述androidmanifest修改.xml和main.xml的不同作用

AlexMichel 的BLOG
用户名:AlexMichel
文章数:64
评论数:13
访问量:511477
注册日期:
阅读量:9541
阅读量:2595
阅读量:518
阅读量:223
51CTO推荐博文
在Activity的onCreate方法中的setContentView(myview)调用之前添加下面代码requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏
按照下面代码示例修改Activity的onResume方法@Override
protected void onResume() {
* 设置为横屏
if(getRequestedOrientation()!=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
super.onResume();
或者在配置文件中对Activity节点添加android:screenOrientation属性(landscape是横向,portrait是纵向)android:launchMode="singleTask" android:screenOrientation="portrait"&
要设置成竖屏设置成 SCREEN_ORIENTATION_PORTRAIT
// ----------------
view.setKeepScreenOn(true)
不加任何旋转屏幕的处理代码的时候,旋转屏幕将会导致系统把当前activity关闭,重新打开。如果只是简单的界面调整,我们可以阻止此问题的发生,屏幕旋转而自己调整屏幕的元素重构。首先我们需要修改AndroidManifest.xml文件:&activity android:name=".Magazine"&&/activity&//修改为:&activity android:name=".Magazine"&&android:configChanges="orientation|keyboard"&&/activity&这样是让程序能够响应旋转屏幕的事件。然后重写onConfigurationChanged方法:@Overridepublic void onConfigurationChanged(Configuration newConfig) {&&// TODO Auto-generated method stub&&super.onConfigurationChanged(newConfig);&&Log.v(" == onConfigurationChanged");&&processLayout();}
//----------------------------
在我们用Android开发过程中,会碰到Activity在切换到后台或布局从横屏LANDSCAPE切换到PORTRAIT,会重新切换Activity会触发一次onCreate方法。
在Android开发中这种情况视可以避免的,我们可以在androidmanifest.xml中的activit元素加入这个属性 android:configChanges="orientation|keyboardHidden" 就能有效避免oncreat方法的重复加载,&
androidmanifest.xml内容如下:红色字体为添加部分
&?xml version="1.0" encoding="utf-8"?&&manifest xmlns:android=""&&&&& package="com.demo"&&&&& android:versionCode="1"&&&&& android:versionName="1.0"&&&& &application android:icon="@drawable/icon" android:label="@string/app_name"&&&&&&&& &activity android:name=".DemoGPS"&&&&&&& &&& android:configChanges="orientation|keyboardHidden"&&&&&&&&&&&&&&&&& android:label="@string/app_name"&&&&&&&&&&&& &intent-filter&&&&&&&&&&&&&&&& &action android:name="android.intent.action.MAIN" /&&&&&&&&&&&&&&&& &category android:name="android.intent.category.LAUNCHER" /&&&&&&&&&&&& &/intent-filter&&&&&&&& &/activity&&&&uses-library android:name="com.google.android.maps" /&
&&& &/application&&&& &uses-sdk android:minSdkVersion="7" /&
&&uses-permission android:name="android.permission.INTERNET"&&/uses-permission&&&& &uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"&&/uses-permission&&&& &uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"&&/uses-permission&&&/manifest&
同时在Activity的Java文件中重载onConfigurationChanged(Configuration newConfig)这个方法,这样就不会在布局切换或窗口切换时重载等方法。代码如下:
&@Override &&& public void onConfigurationChanged(Configuration newConfig)&&& { &&&&&&& super.onConfigurationChanged(newConfig); &&&& if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)&&&& {//land&&&& }&&&& else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)&&&& {//port&&&& }&&& }
//------------------------------------------------------
了这篇文章
类别:未分类┆阅读(0)┆评论(0)android 批量打渠道包 - phenom - ITeye技术网站
博客分类:
打包,是一个经常会遇到的问题,写个脚本就可以解决了.不同的脚本,速度不同.如果使用ant,需要编译,这个时间较长,可以修改下任务,只编译一次就可以了.
sdk里面提供了一堆工具,打包就是用这些工具做的.
在看了几篇文章后,也写了一个类,实现了打包的功能.
需要用到apktool.jar,
原本是python写的一个脚本,具体是哪个大侠,本人也不清楚.
在这里感谢下.
这是python脚本
#!/usr/bin/python
# coding=utf-8
import shutil
def readChannelfile(filename):
f = file(filename)
while True:
line = f.readline().strip('\n')
if len(line) == 0:
channelList.append(line);
def backUpManifest():
if os.path.exists('./AndroidManifest.xml'):
os.remove('./AndroidManifest.xml')
manifestPath = './temp/AndroidManifest.xml'
shutil.copyfile(manifestPath, './AndroidManifest.xml')
def modifyChannel(value):
tempXML = ''
f = file('./AndroidManifest.xml')
for line in f:
if line.find('wap') & 0:
line = line.replace('wap', value)
tempXML += line
output = open('./temp/AndroidManifest.xml', 'w')
output.write(tempXML)
output.close()
tempXML = ''
f = file('./agency.txt')
for line in f:
if line.find('defaultid') & 0:
line = line.replace('defaultid', value)
tempXML += line
output = open('./temp/assets/defaultid.txt', 'w')
output.write(tempXML)
output.close()
unsignApk = r'./bin/%s_%s_unsigned.apk'% (easyName, value)
cmdPack = r'java -jar apktool.jar b temp %s'% (unsignApk)
os.system(cmdPack)
unsignedjar = r'./bin/%s_%s_unsigned.apk'% (easyName, value)
signed_unalignedjar = r'./bin/%s_%s_signed_unaligned.apk'% (easyName, value)
signed_alignedjar = r'./bin/%s_v%s_%s_%s_%s_%s.apk'% (easyName, versionid, productid, value, packtime, customerid)
cmd_sign = r'jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore %s -storepass %s -keypass %s -signedjar %s %s %s'% (keystore, storepass, keypass, signed_unalignedjar, unsignedjar, alianame)
cmd_align = r'zipalign -v 4 %s %s' % (signed_unalignedjar, signed_alignedjar)
os.system(cmd_sign)
os.remove(unsignedjar)
os.system(cmd_align)
os.remove(signed_unalignedjar)
dir = r'./bin/%s'% (value)
os.mkdir(dir)
shutil.move(signed_alignedjar,dir)
channelList = []
apkName = 'dfadfadf.apk'
easyName = apkName.split('.apk')[0]
keystore='./keystore/Android.key'
storepass=''
keypass=''
alianame=''
packtime=''
customerid=''
productid='10'
versionid='1.0.0'
output_apk_dir="./bin"
if os.path.exists(output_apk_dir):
shutil.rmtree(output_apk_dir)
readChannelfile('./channel')
print '-------------------- your channel values --------------------'
print 'channel list: ', channelList
cmdExtract = r'java -jar apktool.jar
d -f -s %s temp'% (apkName)
os.system(cmdExtract)
backUpManifest()
for channel in channelList:
modifyChannel(channel)
if os.path.exists('./temp'):
shutil.rmtree('./temp')
if os.path.exists('./AndroidManifest.xml'):
os.remove('./AndroidManifest.xml')
print '-------------------- Done --------------------'
不废话,直接上代码:
import java.io.BufferedR
import java.io.F
import java.io.FileInputS
import java.io.FileW
import java.io.IOE
import java.io.InputS
import java.io.InputStreamR
import java.text.DecimalF
import java.text.NumberF
import java.util.ArrayL
import java.util.L
* @author: archko
public class JPackage {
ArrayList&String& mChannelList=new ArrayList&String&();
private String mChannelFile="channel";
private String mParamsFile="params";
* 打的包名,
String apkN
* 签名的地址
* 签名密码
* 密钥密码
* 签名的别名
* 打包时间
* 标识,固定的
* 旧的渠道名.就是要替换的位置.
String oldchannel="defaultid";
* 是否分别放入不同的目录中.
static String cmd_header="cmd.exe /C ";
* 需要替换的assets里面的名字.
public void runCmd(String cmd) {
Runtime rt=Runtime.getRuntime();
Process p=rt.exec(cmd_header+cmd);
// p.waitFor();
BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));
String msg=
while ((msg=br.readLine())!=null) {
System.out.println(msg);
} catch (Exception e) {
e.printStackTrace();
public ArrayList&String& readFile(String path) {
ArrayList&String& lines=new ArrayList&String&();
InputStream is=
InputStreamReader reader=
BufferedReader br=
is=new FileInputStream(path);
reader=new InputStreamReader(is, "UTF-8");
br=new BufferedReader(reader);
while ((row=br.readLine())!=null) {
lines.add(row);
} catch (OutOfMemoryError e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
if (null!=br) {
br.close();
if (null!=reader) {
reader.close();
} catch (IOException e) {
e.printStackTrace();
public void readChannels(String path) {
mChannelList=readFile("./"+path);
public void backManifest() throws Exception {
File file=new File("./temp/AndroidManifest.xml");
if (!file.exists()) {
throw new Exception("没有AndroidManifest文件");
File dest=new File("./AndroidManifest.xml");
file.renameTo(dest);
if (!isEmpty(assetsname)) {
file=new File("./temp/assets/"+assetsname);
if (!file.exists()) {
throw new Exception("没有"+assetsname+"文件");
dest=new File("./"+assetsname);
file.renameTo(dest);
private void readParamsFromFile(String[] args) throws Exception {
ArrayList&String& params=readFile("./"+mParamsFile);
System.out.println("params"+params);
if (params.size()&1) {
throw new Exception("打包参数不对.");
for (String ss : params) {
line=ss.split("=");
if ("apkName".equals(line[0])) {
apkName=line[1];
} else if ("keystorepath".equals(line[0])) {
keystorepath=line[1];
} else if ("storepass".equals(line[0])) {
storepass=line[1];
} else if ("keypass".equals(line[0])) {
keypass=line[1];
} else if ("alianame".equals(line[0])) {
alianame=line[1];
} else if ("packtime".equals(line[0])) {
packtime=line[1];
} else if ("versionname".equals(line[0])) {
versionname=line[1];
} else if ("identity".equals(line[0])) {
identity=line[1];
} else if ("customerid".equals(line[0])) {
customerid=line[1];
} else if ("oldchannel".equals(line[0])) {
oldchannel=line[1];
} else if ("splitdir".equals(line[0])) {
splitdir=line[1];
} else if ("assetsname".equals(line[0])) {
assetsname=line[1];
} else if ("assetchannel".equals(line[0])) {
assetchannel=line[1];
System.out.println("参数为:"+String.format("apkName:%s, keystorepath:%s, storepass:%s, keypass:%s, alianame:%s, "+
"packtime:%s, versionname:%s,identity:%s, oldchannel:%s, splitdir:%s",
apkName, keystorepath, storepass, keypass, alianame, packtime, versionname, identity, oldchannel, splitdir));
private void decompileApk() throws Exception {
File file=new File("./temp");
if (!file.exists()) {
file.mkdir();
//System.setProperty("java.class.path", ".;"+System.getProperty("java.class.path"));
String cmd="java -jar apktool.jar d -f -s "+apkName+" temp";
//System.out.println("cmd:"+cmd);
runCmd(cmd);
file=new File("./temp/AndroidManifest.xml");
if (!file.exists()) {
throw new Exception("decompile error.");
file=new File("./temp/res");
if (!file.exists()) {
throw new Exception("decompile error.");
if (!file.exists()) {
throw new Exception("decompile error.");
* %s_v%s_%s_%s_%s_%s.apk"% (easyName, versionid, productid, value, packtime, customerid)
* @param channel
public String generateFileName(String channel) {
StringBuilder sb=new StringBuilder();
sb.append(apkName);
if (!isEmpty(versionname)) {
sb.append("_").append(versionname);
if (!isEmpty(identity)) {
sb.append("_").append(identity);
sb.append("_").append(channel);
if (!isEmpty(packtime)) {
sb.append("_").append(packtime);
if (!isEmpty(customerid)) {
sb.append("_").append(customerid);
sb.append(".apk");
System.out.println("包名:"+sb);
return sb.toString();
public void modifyChannel(String channel) {
String apkName=generateFileName(channel);
System.out.println("替换渠道号:"+oldchannel+"为:"+channel+" apk:"+apkName);
replaceChannels(channel);
if ("true".equals(splitdir)) {
file=new File("./bin/"+channel);
file=new File("./bin/");
if (!file.exists()) {
file.mkdirs();
String unsignApk="./bin/_unsigned.apk";
System.out.println("unsignApk:"+unsignApk);
String cmdPack=String.format("java -jar apktool.jar b temp %s", unsignApk);
runCmd(cmdPack);
String unsignedjar="./bin/_unsigned.apk";
String signed_unalignedjar=String.format("./bin/%s_signed_unaligned.apk", "");
String cmd_sign=String.format("jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore %s -storepass %s"+
" -keypass %s -signedjar %s %s %s",
keystorepath, storepass, keypass, signed_unalignedjar, unsignedjar, alianame);
String signed_alignedjar="";
if ("true".equals(splitdir)) {
signed_alignedjar="./bin/"+channel+File.separator+apkN
signed_alignedjar="./bin/"+apkN
String cmd_align=String.format("zipalign -v 4 %s %s", signed_unalignedjar, signed_alignedjar);
runCmd(cmd_sign);
runCmd(cmd_align);
file=new File(unsignApk);
if (file.exists()) {
file.delete();
file=new File(signed_unalignedjar);
if (file.exists()) {
file.delete();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
private void replaceChannels(String channel) throws IOException {
String manifest=readStringFromFile("./AndroidManifest.xml");
manifest=manifest.replaceAll(oldchannel, channel);
File file=new File("./temp/AndroidManifest.xml");
FileWriter fw=new FileWriter(file);
fw.write(manifest);
fw.close();
if (!isEmpty(assetsname)) {
replaceAssets(channel);
private void replaceAssets(String channel) {
ArrayList&String& strings=readFile("./"+assetsname);
StringBuilder result=new StringBuilder();
for (String s : strings) {
String rs=s.replaceAll(assetchannel, channel);
System.out.println("replace assets:"+rs);
result.append(rs).append("\r\n");
File file=new File("./temp/assets/"+assetsname);
FileWriter fw=
fw=new FileWriter(file);
fw.write(result.toString());
fw.close();
} catch (IOException e) {
e.printStackTrace();
private void build(String[] args) throws Exception {
//System.out.println(System.getProperty("java.class.path"));
readParamsFromFile(args);
readChannels(mChannelFile);
if (mChannelList.size()&1) {
System.out.println("渠道号:"+mChannelList);
decompileApk();
backManifest();
file=new File("./bin/");
System.out.println("file:"+file.exists());
if (file.exists()) {
deleteDir(file);
for (String channel : mChannelList) {
modifyChannel(channel);
public static boolean isEmpty(String s) {
return length(s)==0;
public static int length(final String s) {
return s!=null ? s.length() : 0;
public static String readStringFromFile(String sFileName) {
if (null==(sFileName))
final StringBuffer sDest=new StringBuffer();
final File f=new File(sFileName);
if (!f.exists()) {
FileInputStream is=new FileInputStream(f);
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String data=
while ((data=br.readLine())!=null) {
sDest.append(data);
} catch (IOException ioex) {
ioex.printStackTrace();
} finally {
is.close();
br.close();
} catch (Exception ex) {
ex.printStackTrace();
return sDest.toString().trim();
public static void deleteDir(File dir) {
if (dir==null||!dir.exists()||!dir.isDirectory())
// 检查参数
for (File file : dir.listFiles()) {
if (file.isFile())
file.delete(); // 删除所有文件
else if (file.isDirectory())
deleteDir(file); // 递规的方式删除文件夹
//dir.delete();// 删除目录本身
public static void main(String[] args) throws Exception {
String OS=System.getProperty("os.name").toLowerCase();
if (OS.contains("linux")||OS.contains("mac")||OS.contains("os")) {
cmd_header=" ";
System.out.println("cmd_header:"+cmd_header);
JPackage jPackage=new JPackage();
long start=System.currentTimeMillis();
jPackage.build(args);
long end=System.currentTimeMillis();
String result=millisToString(end, true);
System.out.println("总花费时间:"+result);
static String millisToString(long millis, boolean text) {
boolean negative=millis&0;
millis=java.lang.Math.abs(millis);
millis/=1000;
int sec=(int) (millis%60);
millis/=60;
int min=(int) (millis%60);
millis/=60;
int hours=(int)
DecimalFormat format=(DecimalFormat) NumberFormat.getInstance(Locale.US);
format.applyPattern("00");
if (text) {
if (millis&0)
time=(negative ? "-" : "")+hours+"h"+format.format(min)+"min";
else if (min&0)
time=(negative ? "-" : "")+min+"min";
time=(negative ? "-" : "")+sec+"s";
if (millis&0)
time=(negative ? "-" : "")+hours+":"+format.format(min)+":"+format.format(sec);
time=(negative ? "-" : "")+min+":"+format.format(sec);
39个包,6m左右,2分钟左右完成.
前面的python脚本还存在一些问题,比如环境不好配置,(linux下是可以的,mac下,cygwin下会提示aapt这些找不到,可能是64位的原因).渠道名有空格无法识别啊.
顺便写了两个脚本,bat在windows下用,sh在*nix下用.
最后的包名;pn_v1.0.0_111_3g__abc.apk
所以上面的参数可以不写,比如你的包,没有需要identity这个东西,就可以放空.identity=
就行了.但是不能加参数,需要的话,自己修改源码了.
配置的参数为params文件,上面源码里有了:
apkName=your_pkg.apk
keystorepath=./keystore/Android.key
storepass=your_storepass
keypass=your_keypass
alianame=your_alianame
上面这些不用说了,必须的,但是如果keypass不写,默认与storepass一样.
下面这些影响最后的命名
packtime= 打包的时间,可以为空
customerid=abc 可为空.
identity=111 可为空.
versionname=v1.0.0 可为空.
oldchannel=wap 需要替换的渠道名字,manifest里面的
splitdir=true 是否为单个渠道建立目录,分开放包.
assetsname=assets_channel.txt 如果你要在assets目录下有一个渠道文件,就可以在这里写明.
assetchannel=defaultid assets下的渠道文件中的需要替换的名字.
替换是使用正则,所以看清楚了.不要弄错了.
destApkName=yourakpname 这个是你的apk名字前缀,后面加的,源码在压缩包中,上面的就不修改了.
最后的文件,如果参数都有的话:
myapk_v1.0.0_31_3g__111.apk
channel就是一个文本文件,一行一个渠道,如果是在linux下,使用windows下的此文件,有可能换行符会出现问题,如果是这样,就可以把行尾的删除,再回车换行.
特别说下sh文件:
export JAVA_HOME=/media/archko/res_compile/jdk1.7.0_67
export ANDROID_SDK=/media/archko/linux_res/android-sdk-linux
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$ANDROID_SDK:$ANDROID_SDK/platforms-tools:$ANDROID_SDK/tools:$ANDROID_SDK/build-tools/20.0.0:
这些路径自己设置好.否则可能找不到aapt,这些需要的命令.
最后运行:sh pkg.sh
或双击bat就可以打包了.
或者直接运行java -Xms128m -Xmx512m -jar pkg.jar 再或者你编译了源码,可以
java JPackage来打包.
下载次数: 52
浏览: 205323 次
来自: 福州
好棒!感谢楼主分享
&div class=&quote_title ...
解码过程中,没有显示……
帮了我大忙啊。。。。要在if(event.getAction( ...2256人阅读
一,重要性AndroidManifest.xml是Android应用程序中最重要的文件之一。它是Android程序的全局配置文件,是每个 android程序中必须的文件。它位于我们开发的应用程序的根目录下,描述了package中的全局数据,包括package中暴露的组件 (activities, services, 等等),以及他们各自的实现类,各种能被处理的数据和启动位置等重要信息。&
因此,该文件提供了Android系统所需要的关于该应用程序的必要信息,即在该应用程序的任何代码运行之前系统所必须拥有的信息。一个典型的Android应用程序的结构如下图所示:
二,主要功能它指定了该应用程序的Java包:该包名作为应用程序的一个独特标识。&
它描述了应用程序组件:该应用程序由哪些activity,service,broadcast receiver和content provider组成。它指定了实现每个组件的类以及公开发布它们的能力(例如,它们能持有哪个Intent信息)。这些声明使Android系统知道这 儿有什么组件以及在什么条件下它们可以被载入。&
它决定那些进程将容纳应用程序组件。&
它声明了本应用程序必须拥有哪些许可,以便访问API的被保护部分,以及与其他应用程序交互。&
它也声明了其他应用程序在和该应用程序交互时需要持有的许可。&
它列出了Instrumentation类,可以在应用程序运行时提供简档和其他信息。这些声明仅当应用程序在开发和测试过程中被提供;它们将在应用程序正式发布之前被移除。&
它声明了该应用程序所需的Android API的最小化水平。&
它列出了该应用程序必须链接的库。&
三,主要结构及规则下面列表显示了manifest文件的通常的结构以及它可以含有的元素。每个元素,连同它的所有属性,会在各个单独的文档里进行充分的描绘。&
&?xml version=&1.0& encoding=&utf-8&?&&
&manifest&&&//根节点,描述了package中所有的内容&
& & &uses-permission /& //请求你的package正常运作所需赋予的安全许可。一个manifest能包含零个或更多此元素&
& & &permission /&&&//声明了安全许可来限制哪些程序能使用你的package中的组件和功能。一个manifest能包含零个或更多此元素&
& & &permission-tree /&&&
& & &permission-group /&&
& & &instrumentation /&&&//声明了用来测试此package或其他package指令组件的代码。一个manifest能包含零个或更多此元素&
& & &uses-sdk /&&&//指定当前应用程序兼容的最低sdk版本号&
& & &application&&&//包含package中application级别组件声明的根节点。此元素也可包含 application中全局和默认的属性,如标签,icon,主题,必要的权限,等等。一个manifest能包含零个或一个此元素(不允许多余一个)&
& && &&&&activity&&&//用来与用户交互的主要工具。当用户打开一个应用程序的初始页面时一个activity,大部分被使用到的其他页面也由不同的activity所实现并声明在另外的activity标记中。&
& && && && &&intent-filter&&&//声明了指定的一组组件支持的Intent值&
& && && && && & &action /&&
& && && && && & &category /&&
& && && && && & &data /&&
& && && && && && &&&&type/&&
& && && && && && &&&&schema/&&
& && && && && && &&&&authority/&&
& && && && && && &&&&path/&&
& && && && &&/intent-filter&&
& && && && &&meta-data /&&
& && &&&&/activity&&
& && &&&&activity-alias&&
& && && && &&intent-filter& . . . &/intent-filter&&
& && && && &&meta-data /&&
& && &&&&/activity-alias&&
& && &&&&service&&&//Service是能在后台运行任意时间的组件&
& && && && &&intent-filter& . . . &/intent-filter&&
& && && && &&meta-data/&&
& && &&&&/service&&
& && &&&&receiver&& &//IntentReceiver能使你的application获得数据的改变或者发生的操作,即使它当前不在运行&
& && && && &&intent-filter& . . . &/intent-filter&&
& && && && &&meta-data /&&
& && &&&&/receiver&&
& && &&&&provider&&&//ContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件&
& && && && &&grant-uri-permission /&&
& && && && &&meta-data /&&
& && &&&&/provider&&
& && &&&&uses-library /&&
& && &&&&uses-configuration /&& &
& & &/application&&
&/manifest&
下面是按照字母顺序排列的所有可以出现在manifest文件里的元素。它们是唯一合法的元素;你不能加入你自己的元素或属性。
&activity&&
&activity-alias&&
&application&&
&category&&
&grant-uri-permission&&
&instrumentation&&
&intent-filter&&
&manifest&&
&meta-data&&
&permission&&
&permission-group&&
&permission-tree&&
&provider&&
&receiver&&
&service&&
&uses-configuration&&
&uses-library&&
&uses-permission&&
&uses-sdk&
说明:AndroidManifest.xml文件的结构、元素,以及元素的属性,可以在Android SDK文档中查看详细说明。而在看这些众多的元素以及元素的属性前,需要先了解一下这些元素在命名、结构等方面的规则:&
& & 元素:在所有的元素中只有&manifest&和&application&是必需的,且只能出现一次。如果一个元素包含有其他子元素,必须通过子元素的属性来设置其值。处于同一层次的元素,这些元素的说明是没有顺序的。&
& & 属性:按照常理,所有的属性都是可选的,但是有些属性是必须设置的。那些真正可选的属性,即使不存在,其也有默认的数值项说明。除了根元素&manifest&的属性,所有其他元素属性的名字都是以android:前缀的;&
& & 定义类名:所有的元素名都对应其在SDK中的类名,如果你自己定义类名,必须包含类的数据包名,如果类与application处于同一数据包中,可以直接简写为“.”;&
& & 多数值项:如果某个元素有超过一个数值,这个元素必须通过重复的方式来说明其某个属性具有多个数值项,且不能将多个数值项一次性说明在一个属性中;&
& & 资源项说明:当需要引用某个资源时,其采用如下格式:@[package&:]type&:name&。&例如
&activity android:icon=”@drawable/icon ” . . . &&
& & 字符串值:类似于其他语言,如果字符中包含有字符“\”,则必须使用转义字符“\\”;&
四,详细说明值得一提一些常用之处:&
1,几乎所有的AndroidManifest.xml(以及许多其他Android的xml的文件)在第一个元素中包含了命名空间的声明 xmlns:android=&/apk/res/android&。这样使得Android中各 种标准属性能在文件中使用,提供了大部分元素中的数据。&
2,大部分manifests包含了单个&application&的元素,它定义了所有的application级别组件和属性,并能在package中使用。&
3,任何被用户看作顶层应用程序,并能被程序启动器所用的package,需要包含至少一个Activity组件来支持MAIN操作和LAUNCHER种 类。动作android.intent.action.MAIN指示这是应用程序的入口点。类别 android.intent.category.LAUNCHER将此Activity放在启动器窗口中。
在最外层的&manifest&中包含了包名如 package=&cn.androidlover.demo& 、软件的版本号 android:versionCode=&1& 以及 android:versionName=&1.0&的属性,而里面一层的&application&分支中将可能包含Android程序的 四种对象 Activity、Service、Content Provider以及Receiver。我们每添加上面四个类型中的任一种新对象都需要在androidmanifest.xml文件中添加相应节点,否
则运行时将会产生异常。每一个activity必须要一个&activity&标记对应,无论它给外部使用或是只用于自己的package 中。如果一个activity没有对应的标记,你将不能运行它。
此文件一个重要的地方就是它所包含的intent-filters。这些filters描述了activity启动的位置和时间。每当一个 activity(或者操作系统)要执行一个操作,例如:打开网页或联系簿时,它创建出一个intent的对象。它能承载一些信息描述了你想做什么,你想 处理什么数据,数据的类型,和一些其他信息。Android比较了intent对象中和每个application所暴露的intent-filter中 的信息,来找到最合适的activity来处理调用者所指定的数据和操作。关于intent的更多信息请访问Intent参考页面。
application属性介绍:
有关AndroidManifest.xml文件的application分支我们有必要了解一些常见的属性,这里可以看到一些我们实用的选项,比如允许 调试android:debuggable、任务关系android:taskAffinity,比如我们常见的方式创建一个新的任务实用标记 FLAG_ACTIVITY_NEW_TASK,为程序制定一个主题,可以使用android:theme指向一个主题文件。平时我们创建的程序使用一些 安全敏感项,会需要请求系统许可权限,这里可以使用android:permission来制定相关的许可,每个程序的service、
activity、content provider、receiver都需要在application的节点内实现。有关完整的属性可以查看:
&application android:allowClearUserData=[&true& | &false&]&
& && && && & android:allowTaskReparenting=[&true& | &false&]&
& && && && & android:debuggable=[&true& | &false&]&
& && && && & android:description=&string resource&&
& && && && &&&android:enabled=[&true& | &false&]&
& && && && & android:hasCode=[&true& | &false&]&
& && && && & android:icon=&drawable resource&&
& && && && &&&android:label=&string resource&&
& && && && & android:manageSpaceActivity=&string&&
& && && && &&&android:name=&string&&
& && && && &&&android:permission=&string&&
& && && && &&&android:persistent=[&true& | &false&]&
& && && && &&&android:process=&string&&
& && && && &&&android:taskAffinity=&string&&
& && && && &&&android:theme=&resource or theme& &&
& &&&. . .&
&/application&
另外:Activity的属性常用的可能为android:name和android:label两个,但我们需要了解所有的属性以帮助解决复杂的问题,完整的如下:
android:allowTaskReparenting=[&true& | &false&]
android:alwaysRetainTaskState=[&true& | &false&]
android:clearTaskOnLaunch=[&true&& | &false&]
android:configChanges=[one or more of: &mcc& &mnc& &locale& &touchscreen& &keyboard& &keyboardHidden& &navigation& &orientation& &fontScale&]
android:enabled=[&true& | &false&]
android:excludeFromRecents=[&true& | &false&]
android:exported=[&true& | &false&]
android:finishOnTaskLaunch=[&true& | &false&]
android:icon=&drawable resource&
android:label=&string resource&
android:launchMode=[&multiple& | &singleTop& | &singleTask& | &singleInstance&]
android:multiprocess=[&true& | &false&]
android:name=&string&
android:noHistory=[&true& | &false&]
android:permission=&string&
android:process=&string&
android:screenOrientation=[&unspecified& | &user& | &behind& | &landscape& | &portrait& | &sensor& | &nonsensor&]
android:stateNotNeeded=[&true& | &false&]
android:taskAffinity=&string&
android:theme=&resource or theme&
android:windowSoftInputMode=[one or more of: &stateUnspecified& &stateUnchanged& &stateHidden& &stateAlwaysHidden& &stateVisible& &stateAlwaysVisible& &adjustUnspecified& &adjustResize& &adjustPan&]
从Provider节点中用到的定义,可以看到包含了权限控制、排序方式完整的如下:
&provider android:authorities=&list&&
& && && &&&android:enabled=[&true& | &false&]&
& && && &&&android:exported=[&true& | &false&]&
& && && &&&android:grantUriPermissions=[&true& | &false&]&
& && && &&&android:icon=&drawable resource&&
& && && &&&android:initOrder=&integer&&
& && && &&&android:label=&string resource&&
& && && & android:multiprocess=[&true& | &false&]&
& && && & android:name=&string&&
& && && &&&android:permission=&string&&
& && && &&&android:process=&string&&
& && && &&&android:readPermission=&string&&
& && && &&&android:syncable=[&true& | &false&]&
& && && &&&android:writePermission=&string& &&
&/provider&
而对于服务相关定义如下:
&service android:enabled=[&true& | &false&]&
& && && & android:exported[=&true& | &false&]&
& && && & android:icon=&drawable resource&&
& && && & android:label=&string resource&&
& && && &android:name=&string&&
& && && & android:permission=&string&&
& && && & android:process=&string& &&
&/service&
最后是Broadcast使用的Receiver定义,一般配合和隐式处理。
&receiver android:enabled=[&true& | &false&]&
& && && &&&android:exported=[&true& | &false&]&
& && && &&&android:icon=&drawable resource&&
& && && & android:label=&string resource&& && && && &
& && && & android:name=&string&&
& && && & android:permission=&string&&
& && && & android:process=&string& &&
&/receiver&
总之,AndroidManifest.xml文件虽然看起来复杂,但是,只要我们理清中里面各元素的作用,那么一切就变得简单了。
===================================================================================
每一个Android项目都包含一个清单(Manifest)文件--AndroidManifest.xml,它存储在项目层次中的最底层。清单可以定义应用程序及其组件的结构和元数据。
  它包含了组成应用程序的每一个组件(活动、服务、内容提供器和广播接收器)的节点,并使用Intent过滤器和权限来确定这些组件之间以及这些组件和其他应用程序是如何交互的。
  它还提供了各种属性来详细地说明应用程序的元数据(如它的图标或者主题)以及额外的可用来进行安全设置和单元测试顶级节点,如下所述。
  清单由一个根manifest标签构成,该标签带有一个设置项目包的package属性。它通常包含一个xmlns:android属性来提供文件内使用的某些系统属性。下面的XML代码段展示了一个典型的声明节点:
  &manifest xmlns:android=/apk/res/android package=&com.my_domain.my_app&& [ ... manifest nodes ... ] &/manifest&
  manifest标签包含了一些节点(node),它们定义了应用程序组件、安全设置和组成应用程序的测试类。下面列出了一些常用的manifest节点标签,并用一些XML代码段说明了它们是如何使用的。
  application& 一个清单只能包含一个application节点。它使用各种属性来指定应用程序的各种元数据(包括标题、图标和主题)。它还可以作为一个包含了活动、服务、内容提供器和广播接收器标签的容器,用来指定应用程序组件。
  activity& 应用程序显示的每一个Activity都要求有一个activity标签,并使用android:name属性来指定类的名称。这必须包含核心的启动Activity和其他所有可以显示的屏幕或者对话框。启动任何一个没有在清单中定义的Activity时都会抛出一个运行时异常。每一个Activity节点都允许使用intent-filter子标签来指定哪个Intent启动该活动。
  service& 和activity标签一样,应用程序中使用的每一个Service类都要创建一个新的service标签。(Service标签也支持使用intent-filter子标签来允许后面的运行时绑定。
  provider& provider标签用来说明应用程序中的每一个内容提供器。内容提供器是用来管理数据库访问以及程序内和程序间共享的,第6章将会对其进行详细讲述。
  receiver& 通过添加receiver标签,可以注册一个广播接收器(Broadcast Receiver),而不用事先启动应用程序。广播接收器就像全局事件监听器一样,一旦注册了之后,无论何时,只要与它相匹配的intent被应用程序广播出来,它就会立即执行。通过在声明中注册一个广播接收器,可以使这个进程实现完全自动化。如果一个匹配的Intent被广播了,则应用程序就会自动启动,并且你注册的广播接收器也会开始运行。
  uses-permission& 作为安全模型的一部分,uses-permission标签声明了那些由你定义的权限,而这些权限是应用程序正常执行所必需的。在安装程序的时候,你设定的所有权限将会告诉给用户,由他们来决定同意与否。对很多本地Android服务来说,权限都是必需的,特别是那些需要付费或者有安全问题的服务(例如,拨号、接收SMS或者使用基于位置的服务)。如下所示,第三方应用程序,包括你自己的应用程序,也可以在提供对共享的程序组件进行访问之前指定权限。
  permission& 在可以限制访问某个应用程序组件之前,需要在清单中定义一个permission。可以使用permission标签来创建这些权限定义。然后,应用程序组件就可以通过添加android:permission属性来要求这些权限。再后,其他的应用程序就需要在它们的清单中包含uses-permission标签(并且通过授权),之后才能使用这些受保护的组件。
  在permission标签内,可以详细指定允许的访问权限的级别(normal、dangerous、signature,signatureOrSystem)、一个 label属性和一个外部资源,这个外部资源应该包含了对授予这种权限的风险的描述。
  instrumentation& instrumentation类提供一个框架,用来在应用程序运行时在活动或者服务上运行测试。它们提供了一些方法来监控应用程序及其与系统资源的交互。对于为自己的应用程序所创建的每一个测试类,都需要创建一个新的节点。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:270230次
积分:3340
积分:3340
排名:第4606名
原创:21篇
转载:185篇
评论:68条
(1)(1)(4)(1)(2)(1)(1)(1)(10)(1)(1)(3)(1)(5)(2)(1)(1)(3)(18)(5)(1)(4)(7)(20)(15)(32)(64)}

我要回帖

更多关于 android main.xml 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信