十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
android ndk下面生成动态库so文件的方法很多,但是这里只提供一种方法,更多的生成方法可以看,“ndk 编译静态库”:
创新互联-专业网站定制、快速模板网站建设、高性价比滨江网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式滨江网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖滨江地区。费用合理售后完善,10多年实体公司更值得信赖。
2
fkAdd.c 的内容如下:
#include jni.h
int fkAdd(int nX, int nY)
{
return nX + nY;
}
3
Android.mk 的内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= fkAdd
LOCAL_SRC_FILES:= fkAdd.c
include $(BUILD_SHRRED_LIBRARY)
1、打开 eclipse
2、点击 文件
3、点击 新建
4、点击 other...
1、展开 Android 选项;
2、选择 Android Project from Existing Code;
3、点击 Next
1、输入 Root Director;
2、取消 tests;
3、选中 Copy projects into workspace;
4、点击 Finish;
1、右键工程;
2、选择 Android Tools;
3、Add Native Support...;
点击 Finish
修改android sdk 版本为 4.0.3;
关于如何修改 android sdk 版本:
修改 Min SDK version:15
修改 Target SDK version:19
在jni目录下面新建文件fkAdd.c 的内容如下:
int fkAdd(int nX, int nY)
{
return nX + nY;
}
临时修改 Android.mk 文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#LOCAL_MODULE := hello-jni
#LOCAL_SRC_FILES := hello-jni.c
LOCAL_MODULE := fkaddso
LOCAL_SRC_FILES := fkAdd.c
include $(BUILD_SHARED_LIBRARY)
使用快捷键Ctrl+B编译后可以在libs目录下面看到生成的一些列的
libfkaddso.so文件,如下图所示
// filename: CallbackBundle.java
package com.example.openfiledemo;
import android.os.Bundle;
// 简单的Bundle参数回调接口
public interface CallbackBundle {
abstract void callback(Bundle bundle);
}
[java] view plaincopy
// filename: CallbackBundle.java
package com.example.openfiledemo;
import android.os.Bundle;
// 简单的Bundle参数回调接口
public interface CallbackBundle {
abstract void callback(Bundle bundle);
}
然后的打开文件对话框的一下封装:
SimpleAdapter adapter = new SimpleAdapter(getContext(), list, R.layout.filedialogitem, new String[]{"img", "name", "path"}, new int[]{R.id.filedialogitem_img, R.id.filedialogitem_name, R.id.filedialogitem_path});
this.setAdapter(adapter);
return files.length;
}
@Override
public void onItemClick(AdapterView? parent, View v, int position, long id) {
// 条目选择
String pt = (String) list.get(position).get("path");
String fn = (String) list.get(position).get("name");
if(fn.equals(sRoot) || fn.equals(sParent)){
// 如果是更目录或者上一层
File fl = new File(pt);
String ppt = fl.getParent();
if(ppt != null){
// 返回上一层
path = ppt;
}
else{
// 返回更目录
path = sRoot;
}
}
else{
File fl = new File(pt);
if(fl.isFile()){
// 如果是文件
((Activity)getContext()).dismissDialog(this.dialogid); // 让文件夹对话框消失
// 设置回调的返回值
Bundle bundle = new Bundle();
bundle.putString("path", pt);
bundle.putString("name", fn);
// 调用事先设置的回调函数
this.callback.callback(bundle);
return;
}
else if(fl.isDirectory()){
// 如果是文件夹
// 那么进入选中的文件夹
path = pt;
}
}
this.refreshFileList();
}
}
}
[java] view plaincopy
// filename: OpenFileDialog.java
package com.example.openfiledemo;
SimpleAdapter adapter = new SimpleAdapter(getContext(), list, R.layout.filedialogitem, new String[]{"img", "name", "path"}, new int[]{R.id.filedialogitem_img, R.id.filedialogitem_name, R.id.filedialogitem_path});
this.setAdapter(adapter);
return files.length;
}
@Override
public void onItemClick(AdapterView? parent, View v, int position, long id) {
// 条目选择
String pt = (String) list.get(position).get("path");
String fn = (String) list.get(position).get("name");
if(fn.equals(sRoot) || fn.equals(sParent)){
// 如果是更目录或者上一层
File fl = new File(pt);
String ppt = fl.getParent();
if(ppt != null){
// 返回上一层
path = ppt;
}
else{
// 返回更目录
path = sRoot;
}
}
else{
File fl = new File(pt);
if(fl.isFile()){
// 如果是文件
((Activity)getContext()).dismissDialog(this.dialogid); // 让文件夹对话框消失
// 设置回调的返回值
Bundle bundle = new Bundle();
bundle.putString("path", pt);
bundle.putString("name", fn);
// 调用事先设置的回调函数
this.callback.callback(bundle);
return;
}
else if(fl.isDirectory()){
// 如果是文件夹
// 那么进入选中的文件夹
path = pt;
}
}
this.refreshFileList();
}
}
}
private void openFileBrowse() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");// 文件类型
Intent wrapperIntent = Intent.createChooser(intent, "打开方式");
startActivityForResult(wrapperIntent, 0);
}
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
// String path;
if (resultCode == RESULT_OK) {
if (requestCode == 0) {
if (intent == null) {
Toast.makeText(this, "未选择任何文件", Toast.LENGTH_LONG).show();
return;
}
Uri uri = intent.getData();
if (uri == null) {
Toast.makeText(this, "未选择任何文件", Toast.LENGTH_LONG).show();
return;
}
String scheme = uri.getScheme();
//可能是content,file等等.需要判断其是不是file
如果不是调用文件管理器,可能返回其他
if (scheme != null
("file".endsWith(scheme.toLowerCase()))
String path = uri.getPath();//文件路径
}
}
}
当你需要一个资源文件时,Android系统会在运行时根据当前设备的配置信息从你提供的资源中选择一个文件。为了呈现出Android系统是如何选择一个资源文件的这个流程,假定下面的每个drawable目录包含了相同的图片元素的不同像素版本:
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
同时,假定设备的配置信息如下:
Locale = en-GB
Screen orientation = port
Screen pixel density = hdpi
Touchscreen type = notouch
Primary text input method = 12key
通过比较设备的配置信息和可用的资源文件,Android系统从目录drawable-en-port中选择了图片资源。
系统选择出最佳匹配资源文件的算法思路如下:
1. 首先排除那些与设备的配置信息相矛盾的资源文件。
drawable-fr-rCA/ 目录被排除掉, 因为它跟设备的信息 Locale:en-GB 相矛盾。
drawable/
drawable-en/
drawable-fr-rCA/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
注意例外: 屏幕像素密度也是一个限制条件,如果还有目录没有被排除。 即使设备的屏幕密度是hdpi的, drawable-port-ldpi/目录不会被排除,因为每一个屏幕密度在这里被认为是一个点。 更多有用的信息请参考文档:Supporting Multiple Screens 。
2. 从列表中 (table 2)挑选(下一个)最高优先级的匹配项,进行匹配。
3. 是否没有资源文件目录包含这个限制条件?
o 如果没有, 返回第2步 ,同时看看下一个限制条件。在上面的例子中,很显然是“没有”,因此要循环到“语言”这个限制条件是才会遇到下一个限制条件。
o 如果有, 则转到第4步。
4. 排除那些没有包含限制条件的资源文件目录。在上面的例子中,系统会排除所有不包含“语言”这个限制条件的资源文件目录。
drawable/
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
drawable-port-ldpi/
drawable-port-notouch-12key/
注意例外: 如果限制条件是屏幕像素密度, Android系统会选择跟设备的屏幕密度最相近的那一个。 通常, Android 系统更倾向于缩小一个较大的源图片而不是放大一个较小的源图片。参考 Supporting Multiple Screens。
5. 返回重复执行 2, 3 和4 步,直到仅有一个资源文件目录。在上面的例子中,“屏幕方向”是下一个需要比较的限制条件.。因此,排除那些没有指定屏幕方向的资源文件目录。
drawable-en/
drawable-en-port/
drawable-en-notouch-12key/
这样剩下的目录就只有drawable-en-port这一个了。
因为获取每个需要的资源文件的时候都要执行这个过程,所以需要进一步优化系统的一些不足的地方。 其中一个是,一旦知道了设备的配置信息后,系统会首先排除那些没有匹配项的资源文件目录。 例如, 如果设备配置信息中的“语言”是“英语”(“en”),则不要将那些包含了“语言”这个限制条件但却是其他语言信息的资源文件目录添加到待匹配的资源池中。尽管这样可能会留下那些没有“语言”这个限制条件的资源目录。
对“屏幕尺寸”这个限制条件进行匹配时,如果没有一个更好的资源文件时,系统会使用那些为比当前屏幕小的屏幕设计的资源文件 (例如,如果需要,一个large-size尺寸屏幕的设备会使用normal-size尺寸屏幕的资源文件)。但是,如果可以选择的资源文件所对应的屏幕尺寸都比当前屏幕的尺寸还大,此时系统不会使用这些资源文件,同时如果没有其他更好的资源文件可选的话,你的应用将会崩溃掉。(例如,如果所有的布局资源文件都是以xlarge 为标签的,而当前的设备屏幕是normal-size尺寸的。)
注意: 列表中(table 2)限制条件的优先级比限制条件的数量更加重要,尽管这些限制条件可能会跟设备的配置信息匹配的很好。比如,在第4步的之前,带匹配的资源目录中最后的一项包括三个限制条件(屏幕方向、触屏类型、输入法)可以跟设备信息匹配,但是 drawable-en 目录仅有一个匹配项(语言)。然而,“语言”拥有比其他几个限制条件更高的优先级,所以 drawable-port-notouch-12key 被排除掉。
要了解更多关于如何在你的应用中使用资源文件,请参考Accessing Resources。
转载,仅供参考,祝你愉快,满意请采纳。
选择器在android中使用的非常广泛,点击反馈、选中、使能、聚焦等状态切换都会用到选择器。
一:下面是一个简单的选择器:
android:enterFadeDuration="200" 、android:exitFadeDuration="200":进入新状态或退出旧状态时会有一个200毫秒的渐变动画。这两个属性使用的比较常见,可以使选择器的状态切换更加平滑。
以下几个都是Drawable的属性。
android:autoMirrored="true"对应drawable.setAutoMirrored(),这个属性表示是否将drawable镜像显示,只有在从右往左布局的环境下才会生效。将此属性设置成true,并将语言调节成阿拉伯语便可以看到效果。
android:dither="true"对应drawable.setDither(),这个属性表示是否对图像进行抖动处理。当图像的bit-color较少时,通过颜色值的抖动来增加可用颜色数量,并保持较好的显示效果。
android:visible="true" 对应drawable.setVisible(),设置Drawable是否可见,一般不会影响Drawable的行为,但是它是Drawable是否运行了动画的一个暗示。例如:AnimationDrawable可以通过这个方法启动或者停止动画。
剩下两个属性对应DrawableContainer$DrawableContainerState里面的属性(DrawableContainer是Drawable的一个子类,DrawableContainerState是DrawableContainer的内部类)。
android:constantSize="true":当选择器各个状态的图片大小不一时,设置为 true表示以最大的图片的尺寸显示,设置为false以默认的图片的尺寸显示(控件大小会对现象有影响,需要是包裹内容的)。
android:variablePadding="false" :默认为false,这个属性意义不大,通常不去设置。
二:Item的各种状态,理解起来相对简单,都可以从属性的名字去理解其含义,例如:
状态为加速的时候会显示ic_launcher_m图片,那么是什么加速呢?这就需要自己去分析一下,其实这里指的加速是对View的软件加速或硬件加速。
当给View设置background、foreground或ImageView设置src时只能写android:drawable="id":
当给文字颜色添加选择器的时候必须要写android:color="ARGB|RGB颜色值"
三:注意安卓程序在读取选择器文件时,是从上往下一个一个节点进行遍历的,程序会选择符合当前控件状态的第一个Item的内容。如果一个Item不写任何状态,表示它任何状态都符合, 所以一般最后一个Item是不会写任何状态的(就像if(){}else if(){}else{}语句一样,最后一个包含了剩下的所有情况)。
四:选择器的Item和animated-rotate一起使用。
五:动态创建选择器
动态创建一个简单的选择器:
用一张图片,通过对图片的着色创建选择器:
创建矢量图选择器:
TextView文字颜色选择器:
部分常用状态数组: