Android面试简录——组件2


自定义组件 *

  • Android怎么动态引用组件?
    动态引用:主程序和组件是分离的,组件可以单独升级和卸载。
    静态引用:将组件和主程序一起封装在编译后的目标文件中。
    可以动态引用的组件有:未安装的apk文件、包括class.dex文件的jar文件、JavaScript脚本、四大应用程序组件(Activity,Service,BroadcastReceiver,Content Provider)。
  • 如何将可视组件封装在jar文件中以及如何通过java代码适应不同的屏幕分辨率?
    jar文件可以封装很多类型的组件,如可视组件(对Android SDK原生组件的扩展),Activity,Service,BroadcastReceiver,ContentProvider等。
    封装:直接将可视组件的.class文件放到jar文件中即可,组件使用的资源文件要放到主工程的res目录的相关子目录中。在XML布局文件中使用组件要指定全名(包名+类名)。
    在自定义可视化组件时需要考虑屏幕分辨率的问题,需要将与屏幕分辨率无关的dp或sp转换成实际的像素点:
    DisplayMetrics displayMetrics = new DisplayMetrics();
    displayMetrics.setToDefaults();
    int pixel = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
    dip, displayMetrics);
  • 怎么编写一个自定义可视组件?
    开发模式:
    1.扩展现有的组件。
    2.组合多种组件。
    3.可以从View继承。
  • Android支持的四大应用程序组件可以封装在jar文件中吗?使用时该注意什么?
    可以,并在Android工程中静态引用jar文件。使用时需要在AndroidManifest.xml文件中注册。
  • 如何动态装载apk文件(未安装)的类?
    //my.apk表示要动态加载的apk文件,my_temp.apk表示为了优化临时生产的apk文件
    DexFile dexFile = dalvik.system.DexFile.loadDex(
    "/sdcard/my.apk", "/sdcard/my_temp.apk", 0);
    //装载apk文件中的类并创建该类的对象实例
    Object obj = dexFile.loadClass(
    "mobile.android.file.explorer.widget.Test", null).newInstance();
    //利用反射技术获取getName方法的Method对象
    Method method = obj.getClass().getDeclaredMethod("getName", null);
    //调用类中的方法,并获取方法返回值
    String result = String.valueOf(method.invoke(obj, null));

【拓展】强类型与aidl文件
如果使用强类型访问apk文件中的类,一般需要将该类实现的接口提供给调用者,或者提供一个aidl文件(mobile.android.file.explorer.widget包中),如:
package mobile.android.file.explorer.widget;
interface MyInterface {
String getName();
}
在编译Android工程时ADT会在gen目录中自动生产MyInterface接口,直接引用该接口即可。

  • Android应用程序是否可以动态引用jar文件?
    JVM格式格式的jar文件不能被Android应用程序动态调用,但包含class.dex文件的jar文件可以。
    打包:
    jar cvf my.jar classes.dex
  • 如何判断包含某个Activity Action的Android应用程序是否安装?
    调用PackageManager.queryIntentActivities方法查询系统中是否注册了某个Activity Action,如果未返回任何结果,说明系统中没安装包含指定Activity Action的apk程序。
    PackageManager packageManager = getPackageManager();
    Intent intent = new Intent("com.android.phone.action.TOUCH_DIALER");
    List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(
    intent, PackageManager.GET_INTENT_FILTERS);
    if (resolveInfo.size() == 0)
    Log.d("Activity Action", "Activity Action不存在");

【拓展】判断四大应用程序组件是否安装
1.BroadcastReceiver:(与Activity类似)
PackageManager packageManager = new PackageManager();
Intent intent = new Intent("mobile.android.MYBROADCAST");
List<ResolveInfo> resolveInfos = packageManager.queryBroadcastReceivers(
intent, PackageManager.GET_INTENT_FILTERS);
if (resolveInfos.size() == 0)
Log.d("Broadcast Action", "不存在");
2.Service(AIDL Service):AIDL Service在调用时需要使用bindService进行绑定,如果AIDL Service不存在则绑定失败。
if (! bindService(new Intent("mobile.android.IMyService"),
serviceConnection, Context.BIND_AUTO_CREATE)) {
Log.d("AIDL Service", "不存在");
}
3.ContentProvider:根据ContentResolver对象的相应方法的返回值进行判断。
Uri uri = Uri.parse("content://mobile.android.regioncontentprovider/cities");
Cursor cursor = getContentResolver().query(uri,
new String[] {"city_code as_id", "city_name"}, null, null, null);
if (cursor == null)
Log.d("Content Provider", "不存在");

  • 在Android应用程序中Java与JavaScript如何交互?
    WebView组件——可以执行JavaScript脚本,也允许在JavaScript脚本中执行java代码。
    1. Java执行JavaScript脚本:
    WebView webView = new WebView(this);
    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setWebChromeClient(new WebChromeClient());
    webView.loadDataWithBaseURL(null, s, "text/html", "utf-8", null);
    2.Java与JavaScript间传递数据,JavaScript脚本执行Java代码:
    WebView.addJavascriptInterface(new Object(){
    public void move(int x, int, y) {
    //Java代码
    }
    }, "demo"); //demo为JavaScript中可访问的对象,通过该对象调用move方法
    在JavaScript中调用move方法:
    <script language="javascript">
    window.demo.move(20, 100);
    </script>

【拓展】Java与JavaScript交互的传统方法
在Java代码中通过占位符替换的方式向JavaScript脚本中传递参数。
JavaScript代码:
<script language="javascript">
function myFun(age, salary) {
//JavaScript脚本
};
myFun(#age#, #salary#);
</script>
将整个JavaScript脚本读到内存中,并将#age#和#salary#替换成相应值,再执行JavaScript脚本。
有返回值:使用alert函数弹出一个对话框,或者在JavaScript中通过HTTP请求发送一个返回值。

  • 请描述NDK方法的命名规则,并描述NDK方法中前两个参数的作用。
    jstring Java_调用NDK方法的java类全名_本地方法名(JNIEnv *env, jobject obj) {......}
    例如:调用NDK方法的java类全名:mobile.android.HelloWorldJNI
    本地方法名:process
    jstring java_mobile_android_HelloWorldJNI_process(JNIEnv env, jobject obj) {......}
    JNIEnv
    ~ 当前NDK环境的对象指针,可以通过该参数值访问NDK中的内置成员。
    jobject ~ 调用当前NDK方法的Java对象,可以用该参数值访问调用当前NDK方法的Java对象的成员。

  • NDK程序怎么访问Java类成员?
    根据jobject访问当前NDK方法的Java对象成员。
    java类:
    public class HelloWorldJNI extends Activity {
    String name = "Jobs";
    ......
    }
    NDK代码:
    jstring Java_mobile_android_jni_helloword_HelloWorldJni_setName(JNIEnv* env, jobject obj) {
    jclass cls;
    jfieldID fid;
    cls = (env) -> GetObjectClass(env, obj);
    fid = (
    env) -> GetFieldID(env, cls, "name", "Ljava/lang/String");
    char str;
    char str1 = (char)(
    env) -> GetStringUTFChars(env, (env) -> GetObjectField(env, obj, fid), NULL);
    str = (char
    ) malloc(128);
    memset(str, 0x0, 128);
    strcpy(str, "你好");
    strcat(str, str1);
    return (*env) -> NewStringUTF(env, str);
    }

  • 如何用Java代码让Android Market显示指定的程序以使用户方便下载?
    程序直接调用内置在手机中的Android Market程序进行下载。
    通过Activity Action直接调用Android Market的窗口。
    >让Android Market直接显示我们所期望的程序:
    Uri uri = Uri.parse("market://search?q=应用名称");
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
    >根据应用程序ID查找:
    Uri uri = Uri.parse("market://details?id=mobile.android.library");
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);

  • 请写出安装apk程序的代码
    Intent intent = new Intent(Intent.ACTION_VIEW);
    String filePath = "/sdcard/FileExplorer.apk";
    intent.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
    startActivity(intent);


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容