android开发学习---基础知识学习、如何导入已有项目和开发一个电话拨号器
一.基础知识点学习
1.Android体系结构
如图所示,android 架构分为三层:
(1)最底层是linux内核,主要是各种硬件的驱动,如相机驱动(Camera Driver),闪存驱动(Flash Memory Driver),wifi驱动(Wifi Driver)等
(2)中间一层是库包(libraries)和android运行环境(android runtime),其中库包主要包括一些协议和浏览器内核(webkit)等,android运行环境主要包括核心库包和Dalvik虚拟机
(3)最上面一层是应用层,应用层主要是跟用户直接打交道的各种应用了,如联系人,浏览器,电话等.
这里重点要注意的是dalvik虚拟机,这里简单的和JVM做个比较:
两者区别:
(1)编译后文件格式:
jvm: .java->.class->.jar
dalvik vm: .java->.class->.dex->.odex
(2)基于的架构
jvm:基于栈的架构
dalvik vm:基于寄存器的架构
注:基于寄存器的虚拟机对于更大的程序来说,在它们编译的时候,花费的时间更短。
(3)字节码格式
jvm:零字节地址格式
dalvik vm: 二/三地址的混合形式
注:二/三地址的混合形式执行的效率要高些,但操作需要更多的load/store指令(指令分配次数和内存访问次数),二/三地址占内存多些,但操作更少,访问内存执行数度是一个瓶颈.dalvik vm在编译时优化代码,而不是在运行时,将多个文件整合成一个,整体减少文件个数i/o操作,常量池的引入,提高类查询的速度
2.配置filter
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
这里对应在手机界面中生成程序图标,对生成程序图标这一事件进行监听.
二.如何导入已有android项目(以apidemos为例)
1.ctrl+n==>选择Android Sample Project
2.选择要导入的Android sdk sample,这里选择2.2
3.选择具体的sample,这里选择ApiDemos.
4.点击Finish后,出现下图所示sample
5.然后ctrl+F11运行到模拟器上.
注:如果启动过程中出现如下类似错误,那么查看项目下一个依赖包 Android Dependencies,在eclipse中右键这个文件夹,在Build Path选项中选择 remove it from build path,然后ctrl+F11运行到模拟器上.
[2014-02-25 00:53:19 - Dex Loader] Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
[2014-02-25 00:53:19 - HelloWorld] Conversion to Dalvik format failed: Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
与导入sample非常类似,导入其他项目,选择Android Project form Existing Code==>项目路径==>next===>finish即可.如下图所示:
二、案例 android下的电话拨号器
新建一个名称为and的android项目,以android 2.2 sdk为底包进行开发
然后一直Next直至finish
1、效果截图
1)初始界面:
2).输入110,点击拨打
3)通话记录
2、代码分析
/and/res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <EditText
android:id="@+id/et_dial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:phoneNumber="true"
android:singleLine="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="54dp"
android:hint="@string/hint"
android:ems="10" >
<requestFocus />
</EditText> <!-- 方法四 -->
<Button
android:id="@+id/bt_dial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/et_dial"
android:layout_below="@+id/et_dial"
android:onClick="dial"
android:text="拨 打" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/et_dial"
android:layout_alignParentTop="true"
android:layout_marginTop="32dp"
android:clickable="true"
android:onClick="info"
android:text="@string/info" /> </RelativeLayout>
注:LinearLayout (线性布局)、AbsoluteLayout(绝对布局)、RelativeLayout(相对布局)、TableLayout(表格布局)、FrameLayout(帧布局),这里采用的是相对布局.
android:onClick="xxx" ,这里xxx对应的是MainActivity.java中的xxx方法,当点击时触发此方法.
/and/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources> <string name="app_name">and</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="hint">在这里输入手机号码</string>
<string name="info">请输入要拨打的手机号码:</string>
</resources>
注:这里主要用来配置一些常量,供其它程序调用.
/and/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amos.and"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.CALL_PHONE"/> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.amos.and.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>
注:注意权限分配问题
/and/src/com/amos/and/MainActivity.java
package com.amos.and; import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText; /**
* @ClassName: MainActivity
* @Description: android开发实例,自定义实现电话拨号器
* @author: amosli
* @email:amosli@infomorrow.com
* @date 2014年2月25日 下午6:53:29
*/
public class MainActivity extends Activity implements OnClickListener{
public static String tag = "MainActivity";
//以内部成员变量的方式定义输入框,在加载主界面的时候就把此变量加载到内存中去,避免多次加载
private EditText mEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = (EditText) MainActivity.this.findViewById(R.id.et_dial);
//得到了activity界面上的button的引用
Button button = (Button) this.findViewById(R.id.bt_dial);
/*
button.setOnClickListener(new OnClickListener() {
//方法二,使用匿名内部类的方式注册一个onClick监听事件
@Override
public void onClick(View arg0) {
String phonenum = mEditText.getText().toString();
Log.i(tag, phonenum);// 输出手机号码
Log.e(tag, "error");
Log.d(tag, "debug");
Log.v(tag, "verbose");
Log.w(tag, "warn");
System.out.println("assert:"+Log.ASSERT);
Intent intent = new Intent();// 意图,代表要执行动作的一个意图
// 拨打动作,110代表的是一个data
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+phonenum));
startActivity(intent);
}
});*/ //方法三:使用全局定义的switch进行事件的监听
// button.setOnClickListener(this); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} //方法三:使用全局定义的switch进行事件的监听,企业中一般常用此方法
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_dial:
String phonenum = mEditText.getText().toString();
Log.i(tag, phonenum);// 输出手机号码
Log.e(tag, "error");
Log.w(tag, "这是方法三");
Intent intent = new Intent();// 意图,代表要执行动作的一个意图
// 拨打动作,110代表的是一个data
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phonenum));
startActivity(intent);
break;
}
;
}
public void dial(View v){
String phonenum = mEditText.getText().toString();
Log.i(tag, phonenum);// 输出手机号码
Log.e(tag, "error");
Log.d(tag, "debug");
Log.v(tag, "verbose");
Log.w(tag, "warn");
System.out.println("assert:"+Log.ASSERT);
Intent intent = new Intent();// 意图,代表要执行动作的一个意图
// 拨打动作,110代表的是一个data
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+phonenum));
startActivity(intent);
}
public void info(View v){ Log.i(tag, "提示信息被点击了一次!") ;
}
//方法一,自定义实现OnclickListener的内部类
private class MyButtonOnClickListner implements OnClickListener {
@Override
public void onClick(View v) {
String phonenum = mEditText.getText().toString();
Log.i(tag, phonenum);// 输出手机号码
Log.e(tag, "error");
Log.d(tag, "debug");
Log.v(tag, "verbose");
Log.w(tag, "warn");
System.out.println("assert:"+Log.ASSERT);
Intent intent = new Intent();// 意图,代表要执行动作的一个意图
// 拨打动作,110代表的是一个data
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+phonenum));
startActivity(intent);
}
}
}
注:这里主要实现了用户输入号码后,点击拨打按钮后,电话拨出情形. 这里用了四种方法去实现拨打动作,推荐第三次方法,更灵活,维护更方便,具体实现可以参见注释.
3、实现过程中出现的问题及解决办法
出现如下所示的提示信息:
02-25 18:03:45.164: E/AndroidRuntime(681): FATAL EXCEPTION: main
02-25 18:03:45.164: E/AndroidRuntime(681): java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.CALL dat=tel:xxx-xxx-xxxx cmp=com.android.phone/.OutgoingCallBroadcaster } from ProcessRecord{40592aa8 681:com.amos.and/10034} (pid=681, uid=10034) requires android.permission.CALL_PHONE
02-25 18:03:45.164: E/AndroidRuntime(681): at android.os.Parcel.readException(Parcel.java:1322)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.os.Parcel.readException(Parcel.java:1276)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1351)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1374)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.app.Activity.startActivityForResult(Activity.java:2827)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.app.Activity.startActivity(Activity.java:2933)
02-25 18:03:45.164: E/AndroidRuntime(681): at com.amos.and.MainActivity$MyButtonOnClickListner.onClick(MainActivity.java:49)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.view.View.performClick(View.java:2485)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.view.View$PerformClick.run(View.java:9080)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.os.Handler.handleCallback(Handler.java:587)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.os.Handler.dispatchMessage(Handler.java:92)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.os.Looper.loop(Looper.java:123)
02-25 18:03:45.164: E/AndroidRuntime(681): at android.app.ActivityThread.main(ActivityThread.java:3683)
02-25 18:03:45.164: E/AndroidRuntime(681): at java.lang.reflect.Method.invokeNative(Native Method)
02-25 18:03:45.164: E/AndroidRuntime(681): at java.lang.reflect.Method.invoke(Method.java:507)
02-25 18:03:45.164: E/AndroidRuntime(681): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
02-25 18:03:45.164: E/AndroidRuntime(681): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
02-25 18:03:45.164: E/AndroidRuntime(681): at dalvik.system.NativeStart.main(Native Method)
02-25 18:03:45.214: W/ActivityManager(97): Force finishing activity com.amos.and/.MainActivity
02-25 18:03:45.814: W/ActivityManager(97): Activity pause timeout for HistoryRecord{40747168 com.amos.and/.MainActivity}
仔细一看是权限问题,权限是用来保护用户隐私的,当用户安装应用时会提示所需要的权限
解决方法如下图所示:添加一个permission: <uses-permission android:name="android.permission.CALL_PHONE"/>
然后保存即可。
4.将开发好apk安装到自己手机上
从项目bin目录下拷贝apk文件,我这里是: D:\develop\and\bin\and.apk,安装过程中会发现有提示信息说应用会拨打电话。
5.关于调试项目
选择项目==>鼠标右键,Debug As -->Android Application==>在要调试的地方加上断点,即可.
如果要调试真机,而非模拟器,如果出现不能调试的问题,那么,可以参见下图配置:
AndroidManifest.xml-->Application-->Debuggable-->true ,然后保存即可。
6.本文源码:
https://github.com/amosli/android.git
android开发学习---基础知识学习、如何导入已有项目和开发一个电话拨号器的更多相关文章
- Java学习---基础知识学习
2016-07-23 周六 利用键盘输入的时候需要抛出异常 ,直接快捷键 ctrl + 1 ;定义数组 int score[] = new int[4] ; 只有4个数字BufferedRead ...
- HTML学习---基础知识学习
1.1. HTML 1.为什么要有HTML? "Hello" "<h1>Hello</h1>" - 浏览器渲染时使用一套HTML规则, ...
- android之电话拨号器
在android入门的案例中,除了HelloWorld这个经典案例,还有一个电话拨号器需要掌握,现在我就来个电话拨号器的示范,毕竟大牛也是从菜鸟进化而来的. 首先你应该知道自己要设置怎样的UI,然后创 ...
- [Android]电话拨号器开发
继续今天的Android,经过昨天大体了解了Android开发的一些基本文件结构,今天来做一个电话拨号器! 预期达到的效果 实现过程 首先还是按照昨天第一篇教程,新建一个项目叫PhoneCall的An ...
- Objective-c基础知识学习笔记
Objective-c基础知识学习笔记(一) 一直有记录笔记的习惯.但非常久没分享一些东西了,正好上半年開始学习IOS了,如今有空写点.因开发须要,公司特意为我们配置了几台新MAC.还让我们自学了2周 ...
- Matrix学习——基础知识
以前在线性代数中学习了矩阵,对矩阵的基本运算有一些了解,前段时间在使用GDI+的时候再次学习如何使用矩阵来变化图像,看了之后在这里总结说明. 首先大家看看下面这个3 x 3的矩阵,这个矩阵被分割成4部 ...
- 韩天峰博客 php基础知识学习记录
http://rango.swoole.com 写好PHP代码真的不容易,给大家几个建议: 慎用全局变量,全局变量不好管理的,会导致你的代码依赖于全局变量,而耦合度太高. 一定不要复制粘贴代码,可重用 ...
- GCC基础知识学习
GCC基础知识学习 一.GCC编译选项解析 常用编译选项 命令格式:gcc [选项] [文件名] -E:仅执行编译预处理: -S:将C代码转换为汇编代码: -c:仅执行编译操作,不进行连接操作: -o ...
- (转)Linux基础知识学习
Linux基础知识学习 原文:http://blog.csdn.net/ye_wei_yang/article/details/52777499 一.Linux的磁盘分区及目录 Linux的配置是通过 ...
随机推荐
- js遍历Object所有属性
在js中经常需要知道Object中的所有属性及值,然而若是直接弹出Object,则是直接显示一个对象,它的属性和值没有显示出来, 不是我们想要的结果,从而需要遍历Object的所有属性. var ob ...
- Linux下配置nfs并远程挂载
nfs是网络文件系统,允许一个节点通过网络访问远程计算机的文件系统,远程文件系统可以被直接挂载到本地,文件操作和本地没有区别,如果是局域网的nfs那么io的性能也可以保证,下面就以CentOS 7.x ...
- linux命令大全网站
一. linux命令大全网站 http://man.linuxde.net/watch
- Python练习环境搭建-引入预定义数据
学习Python,有大量的需要在交互式环境下练习的项目,这时数据来源就很麻烦了,手工输入太慢,写到程序中,运行方便,但各种实验又不方便.昨天试了半天也无法从vscode完美地跳出到交互环境. 今天反过 ...
- HDU 1541 Stars (线段树)
Problem Description Astronomers often examine star maps where stars are represented by points on ...
- artTemplate 原生 js 模板语法版
在页面中引用模板引擎: <script src="dist/template-native.js"></script> 下载 表达式 <% 与 %&g ...
- 一步一步教你搭建和使用FitNesse
啄木鸟之家大吕 敏捷测试已成为现在式,尽早和持续的反馈成为各研发团队的必选项.测试同学也需要跟上这个趋势.除了“找bug”.“分析需求”.“功能测试”,还需考虑“交付质量.一次做对.在没有用户界面情况 ...
- Win10远程桌面出现身份验证错误要求的函数不受支持
Win10更新了,远程连不上了,还是手动来修改,用户体验不好,差评! 解决方法: 在本地(而非远程机),运行 gpedit.msc,打开本地组策略:计算机配置>管理模板>系统>凭据分 ...
- android中使用toolbar
系统默认使用的是ActionBar,就是界面中的标题栏,但是由于ActionBar设计的原因,被限定只能位于活动的顶部,从而不能实现Material Design效果,所以官方建议使用Toolbar替 ...
- SpringBoot添加对Mybatis的支持
1.修改maven配置文件pom.xml,添加对mybatis的支持: <dependency> <groupId>org.mybatis.spring.boot</gr ...