你的位置:首页 > 操作系统

[操作系统]Android学习过程中的一些基础笔记


【Activity】
创建一个Android Activity
http://blog.sina.com.cn/s/blog_4ca9ceef0100yjft.html

 

 



Activity <!-- 在Android中加注释 -->
================================
* 理解成窗口
* 在窗口中可以设置显示不同的界面
* 在 Activity 类中,
要编写代码,控制界面上控件的交互显示

* 一般情况下,一个窗口只对应显示一个界面

* 从一个 Activity 启动另一个 Activity

1) 写纸条

Intent intent =
new Intent(
当前窗口对象,
目标窗口类);

2) 传纸条

startActivity(intent);

Intent intent=getIntent();
PageModule module =(PageModule)intent.getSerializableExtra("module"); //序列化的类


控件大小
width="40dp"
文字大小
textSize="40sp"

监听器
====================================


布局 //以后改布局时如果有两个layout,注意要同时改两个布局的代码(不然findViewById容易报空)//String和drawable可以自己灵活的寻找,但layout不可以
====================================
* 相对布局 RelativeLayout
* 线性布局 LinearLayout
* 表格布局 TableLayout
* 帧布局 FrameLayout //框架布局
* 网格布局 GridLayout

相对布局 RelativeLayout //退拽操作只支持相对布局
//相对布局如果是放入绝对布局中,相对布局要使用绝对布局的params作为自己在绝对布局中的定位
=================================== //可重合
* 停靠父控件边界

alignParentTop 最上边 //="true"
alignParentRight 最右边
alignParentBottom 最底边
alignParentLeft 最左边

* 相对父控件居中

centerInParent 正中间 //="true"
centerHorizental 水平居中 Y轴
centerVertical 垂直居中 X轴

* 停靠周围控件边界

above 其他控件上边 挨着 //="@id/bt4"
below 其他控件下边
toLeftOf 其他控件左边
toRightOf 其他控件右边

* 与周围控件边界对齐

alignTop 与其他控件上边对齐 //="@id/bt5"
alignRight 与其他控件右边对齐
alignBottom 与其他控件下边对齐
alignLeft 与其他控件左边对齐
alignBaseline 与其他控件文本基线对齐

width="wrap_content" //包裹内容
="match_parent" //与父控件相匹配

"alignParentBottom" 最底边在代码中的实现方式
RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
lp2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);


线性布局 LinearLayout
========================================
<LinearLayout orientation放在布局内> //布局内不重合

* 布局方向 //要么是垂直方向一个一个摆放,要么是水平方向一个一个摆放
//默认水平方向,在最上面
orientation= //
horizental //水平在上面
vertical //垂直在左边

* 按比例分配剩余空间

weight比例= //如果有三个数,一个不变,剩下两个加weight,它们两个就会按比例占据剩下的部分
1 //把要设置比例的按钮的widht设置为0dp
1.5
2.3
5.7
3

*) 垂直布局中,height="0dp" //垂直布局中,每一个部分都只能在自己那一行平移。
*) 水平布局中,width="0dp" //水平布局中,每一个部分都只能在自己那一列上下移动。 //1:37

* layout_gravity
重力引力

top
right
bottom
left
center
center_horizental
center_vertical

*) 垂直布局:
left
right
center_horizental
*) 水平布局:
top
bottom
center_vertical

表格布局 TableLayout
===================================== //布局行数不重合
<TableLayout stretchColumns="1,2"放在布局内> //拉伸相应的列使平均分布
* <TableRow>

表格的行,
在其中,添加其他控件

* 拉伸的列

strechColumns="0" //拉宽第1列
strechColumns="0,2" //拉宽第1和3列
strechColumns="2,3" //拉宽第3和第4列
strechColumns="1,2,3" //拉宽第2第3第4列

在表格布局中按钮的宽度是默认的匹配父控件,即使设定了android:layout_width="wrap_content"也没用
设置高度有用

帧布局 FrameLayout
======================================= //可重合
* 可以在控件上,
覆盖添加其他控件 //比如菜单

* layout_gravity
重力引力

top
right
bottom
left
center
center_horizental
center_vertical

right|center_vertical //右同时垂直居中
bottom|center_horizental //下同时水平居中

marginBottom="-80dp" //外边距 下面的外边距-80dp,有一部分在界面外 //控件的下边距

网格布局 GridLayout //与表格布局相识,但更复杂
==========================================
<GridLayout android:columnCount="4"放在布局内> //布局内不重合

是安卓4.0之后出来的版本才有的控件,不能在安卓2.2,2.3等低版本上使用
会报错,要在目录中倒数第四个文件中进行修改成只支持4.0以上版本,切换到代码页面进行改写
把支持的最低版本8(安卓2.3.3)改为14(安卓4.0)
* columnCount //只设置列数
列的数量 //

* column //放在控件内,比如Button内
制定放置的列

column="0" //下标0表示第一列
column="3"

* <Space /> //表示一个空格

* rowSpan="2" //放在控件内 //跨两行 //fill_vertical //填满所跨的行
跨行

* columnSpan
跨列

* layout_gravity //使其填满所跨的行或列

fill
fill_horizental
fill_vertical //填满所跨的行

* <Space />
添加空白

---------------------------------------------------------------------------------------------------------------------------
【layout】 //分开布局
<ImageView
android:id="@+id/action_favor"

android:src="@drawable/ic_action_favor" />

【values/styles】
<style name="toolbar_action">
<item name="android:gravity">center</item>
<item name="android:layout_gravity">center</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:scaleType">center</item>
<item name="android:minWidth">44.0dip</item>
<item name="android:layout_weight">0.0</item>
</style>

【drawable】 //ic_action_favor.<?<selector
<item android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/ic_action_favor_on_pressed" />
<item android:state_selected="true" android:drawable="@drawable/ic_action_favor_on_normal" />
<item android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/ic_action_favor_pressed" />
<item android:drawable="@drawable/ic_action_favor_normal" />
</selector>


---------------------------------------------------------------------------------------------------------------------------





【光标】 // <requestFocus />
<EditText
android:id="@+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="14dp"
android:ems="10"
android:hint="@string/title_1_1" >

<requestFocus />
</EditText>


【航空订票】
1.在res中导入解压后的drawable-hdpi文件夹,内面是要用到的各种图片
2.在libs中导入 ABS_DATASOURCE_v2.jar, 通过Build-Path导入 存着很多账号密码信息

【padding】 //内边距
android:paddingLeft="20dp" //使控件内的文字的左边的外边距为20dp 文字的左边距
【margin】 //外边距
marginBottom="-80dp" //外边距 下面的外边距-80dp,有一部分在界面外 //控件的下边距

【开始时】
//先设置标题栏 (隐藏标题栏)
//向安卓系统发送请求,请求系统把窗口标题栏隐藏掉
requestWindowFeature(Window.FEATURE_NO_TITLE);
//可以让背景充满整个手机屏幕,连电量也遮住,且背景不会变色,依然是白色。
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//再显示界面
setContentView(R.layout.activity_main);

//可以让背景充满整个手机屏幕,连电量也遮住,不过屏幕会变黑
在AndroidManifest. android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

//可以让背景充满整个手机屏幕,连电量也遮住,且屏幕不会变黑
在AndroidManifest. android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >

//请求系统把窗口标题栏隐藏掉
在AndroidManifest. android:theme="@android:style/Theme.Holo.NoActionBar">

//可以让页面只显示中间一小块设置成小窗口样式,而且背景还会变成黑色
在AndroidManifest. android:theme="@android:style/Theme.Dialog"

//可以让屏幕无法横屏
在AndroidManifest. android:screenOrientation="portrait"

//登入状态
android:launchMode="standard" //启动模式 //后面有详细介绍

//可以让标题栏变成明亮色
在AndroidManifest. android:theme="@android:style/Theme.Holo.Light"

【获得控件】
private void setViews() {
bt1=(Button)findViewById(R.id.button1 );
}

【设置监听器】
【跳转窗口】 //跳转页面
private void setListeners(){
bt1.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
Intent ents=new Intent(MainActivity.this, //当前窗口 //写纸条
RelativeLayout.class); //目标窗口
startActivity(ents); //传纸条

}
});
}
*【实现功能】
bt1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
chaxun();

}
});

 

【吐司】 //一个小的黑色的提示框
Toast.makeText(this, "用户名或密码错误!\n\t\t登入失败",
Toast.LENGTH_SHORT).show();

【颜色】
android:background="#0000"
view.setBackgroundColor((int) Long.parseLong("0000000f", 16)); //(int) Long.parseLong("0000000f", 16) 等于15

1.textview.setTextColor((int) Long.parseLong("0000000f", 16)); //(int) Long.parseLong("0000000f", 16) 等于15
2.textview.setTextColor(Color.rgb(255, 255, 255));
3.textview.setTextColor(Color.parseColor("#FFFFFF"));
4.Resources resource = (Resources) getBaseContext().getResources();
ColorStateList csl = (ColorStateList) resource.getColorStateList(R.color.my_color);
if (csl != null) {
tv.setTextColor(csl);
}


【GridView】
九宫格 android:stretchMode="columnWidth",缩放与列宽大小同步

【scale】
android:scaleType="centerCrop" //横着拉长布满整个空间 一个细长的图片控件
例如:
<ImageView
android:id="@+id/ib"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/shadow"
android:layout_below="@id/bt2"
android:scaleType="centerCrop"
/>
【把数组加到ListView列表控件】
//在lv中显示cities的数据 //列表控件
ArrayAdapter<String> adapter =new ArrayAdapter<String>(this, //this前面可能会加一个什么什么Activity,比如BranchSearchActivity.this
android.R.layout.simple_list_item_1,cities); //android.R.layout.simple_list_item_1系统自带
lv.setAdapter(adapter);
方法二
stud=new String[]{"关羽","张飞","赵云","马超","黄忠"};
int resource=R.layout.listview_item; //listview_item是自己定的列表id
adapter=new ArrayAdapter<String>(this, resource,stud);
lv=(ListView)findViewById(R.id.students );
lv.setAdapter(adapter);

【把数组加到Spinner下拉菜单】
//在sp中显示cities的数据 //下拉菜单
adapter =new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,cities);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp.setAdapter(adapter);

getSelectItem() //不知道是不是这个

【AndroidManifest】 //的一些规则 ;文件 ;清单
//写入到sdcord内存卡中,需要添加权限
在倒数第四个文件AndroidManifest中第三项Permissions添加权限,add第四个User Permission(权限)。
然后再name下选择要添加的权限android.permission.WRITE_EXTERNAL_STORAGE,
之后把左边的点一下,就确定了。

DDMS的File Explorer 在mnt内有一个sdcard


/sdcard/ ----虚拟路径,指向/mnt/sdcard/
/mnt/sdcard/ ----真实路径


【权限】
需要加权限 //将数据序列化成<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> //访问网络状态,判断有没有网

【icon】
换App的应用封面图片时,调用图片时,不用加后缀
<application
android:icon="@drawable/goodk"

【menu】
给自己设置的删除按钮加图片时,
<menu <item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
<item
android:id="@+id/delete"
android:orderInCategory="101"
android:showAsAction="always"
android:title="删除"
android:icon="@drawable/ic_menu_delete"/>
</menu>


【导入API源代码】
第三个
D:\Android\sdk\sources

【Context】 //环境对象、上下文对象、场景对象
=====================================
* Android 四大组件的父类

Activity //窗口 活动 //显示界面(显示的界面都是继承activity完成的)
Service //服务 //服务(后台运行的,可以理解为没有界面的activity)
ContentProvider //内容提供者;内容供应商 //数据通信(数据之间通信,同个程序间数据,或者是不同程序间通信)
BroadcastReceiver //广播接收器; //广播(做广播,通知时候用到)

【Application】 应用
当在Application中加载ImageLoader配置参数时,要在AndroidManifest. <application
android:name="com.tarena.myyself.activity.MyApplication" //添加name属性,才能加载
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light.NoActionBar" >

* 翻译为: 环境对象、上下文对象、场景对象

* 提供一组与底层 Android 系统通信的方法




【res】 目录
================================================
* 资源目录
* 会自动生成资源访问 id
* 该目录下的文件会被编译
* layout 子目录,界面
View v =
getLayoutInflater().inflate(R.layout.main)

【LayoutInflater】
LayoutInflater inflater = activity.getLayoutInflater();
View layout = inflater.inflate(R.layout.dialog_layout, null);

LayoutInflater inflater = this.getLayoutInflater();
View layout = inflater.inflate(R.layout.dialog_layout_only_enter, null);



【values】 子目录中,存放一些“值” 包括: 字符串、数组、颜色值...
【设定语言文字】 //要切换到中文输入法们只需要把安卓系统的语言改成中文就可以了。
在res目录下新建(Folder)
【values-zh-rCN】-----strings.zh语言 CN中国
en rUK 英国
en rUS 美国
zh rHK 香港

可以有不同语言版本,例如:
values-zh-rCN
values-语言-r地区

Java部分:
tv=(TextView)findViewById(R.id.textView1 );
Resources res =getResources(); //指向res
String s=res.getString(R.string.str1); //获得字符串
String[] a1=res.getStringArray(R.array.arr1); //获得字符串数组
int[] a2 =res.getIntArray(R.array.arr2); //获得整形数组
int c1=res.getColor(R.color.color1); //获得颜色
int c2=res.getColor(R.color.color2);

tv.setText(s);
tv.append("\n"+Arrays.toString(a1)); //数组转化为字符串
tv.append("\n"+Arrays.toString(a2));
tv.setBackgroundColor(c1);
tv.setTextColor(c2);
Android部分:
英文 //values
<?<resources>
<string name="app_name">day2302_资源目录</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>

<string name="str1">My String!</string>
<string-array name="arr1">
<item>aaa</item>
<item>bbb</item>
<item>ccc</item>
</string-array>
<integer-array name="arr2">
<item>222</item>
<item >444</item>
<item >666</item>
</integer-array>
<color name="color1">#fff</color>
<color name="color2">#00f</color>
</resources>


中文 //values-zh-rCN //要切换到中文输入法们只需要把安卓系统的语言改成中文就可以了。
<?<resources>
<string name="app_name">23天项目2_资源目录</string>
<string name="action_settings">Settings</string>
<string name="hello_world">师姐你好!</string>
<string name="str1">我的字符串!</string>
<string-array name="arr1">
<item>嗷嗷嗷</item>
<item>白冰冰</item>
<item>长城长</item>
</string-array>
<integer-array name="arr2">
<item>222</item>
<item >444</item>
<item >666</item>
</integer-array>
<color name="color1">#fff</color>
<color name="color2">#00f</color>
</resources>

【raw】 子目录下的文件不会编译,会生成资源访问 id //文本文档

in = getResources().openRawResource(R.raw.xxx);
例子:
在res目录内新建
raw ----abc
raw-ch-rCN ----abc(必须小写) //R会引用 //改成中文输入法之后,就会显示带-ch-rCN的部分
try {
BufferedReader in=new BufferedReader(new InputStreamReader( //输入流在中文模式下时指向raw-ch-rCN/abc ;在没设定模式下指向raw/abc
res.openRawResource(R.raw.abc),"GBK")); //InputStream in=res.openRawResource(R.raw.abc) //res在上面新建的
String line;
while((line=in.readLine())!=null){
tv.append("\n"+line);
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}






getResources() 方法
----------------------------------------------
获得一个资源访问对象 Resources

Resources
----------------------------------------------
openRawResource(文件资源id) 创建 raw 文件中的文件流
getString(id) 获得资源字符串
getColor(id) 获得颜色值
getStringArray(id) 获得字符串数组
getIntArray(id) 获得整数数组

例子:
在res目录内新建
英文中文 try {
int type;
while((type=p.next())!=1){
if(type== s=p.getText();
tv.append("\n"+s);
}
}

} catch (Exception e) {
e.printStackTrace();
}
【pull解析】 //类似于pull解析
private void readChatServer() {
R. int eventType = while (eventType != if (eventType == String tagName = if ("host".equals(tagName)) {
host = }
if ("serviceName".equals(tagName)) {
serviceName = }
if ("port".equals(tagName)) {
port = Integer.parseInt( }
}
eventType = }
}

 

 



【adb】
在DDMS中的左边的倒三角型下有一个reset adb


【Assets】 //资产文件 //资产,只能读取,无法写入
================================================
* 存放在 项目/assests 文件夹中的文件,
可通过以下方法访问

* 不生成资源 id

* 任意创建子目录

getAssets().poen(文件名)

getAssets() 返回 AssetManager 对象

AssetManager - 资产管理对象
----------------------------------
open(String fileName) 创建文件流
list(String path) 列出文件
例子:
可以新建子目录 目录abc-文件a和b和c
res无法新建子目录
例子:
tv=(TextView)findViewById(R.id.textView2 );
try {
AssetManager am =getAssets(); //指向assets
String[] list =am.list("abc"); //收集一个数组
tv.setText("assets/abc目录列表");
for(String name:list){
tv.append("\n"+name);
}
InputStream in=am.open("abc/a"); //读abc/a
tv.append("\n文件n的第一个字节");
tv.append("\n"+in.read());
in.close();
} catch (Exception e) {
e.printStackTrace();
}

【透明度】
0到255,0为完全透明,255为不透明

【重心gravity】 //http://blog.csdn.net/aminfo/article/details/7784229
CENTER_HORIZONTAL "gravity": 1,
CENTER_VERTICAL 16
CENTER 17
BOTTOM 80
TOP 48
LEFT 3
RIGHT 5

【Application】
=========================================
* Context的子类

* 在应用启动时自动创建的一个实例,
一个应用中,只有唯一的一个实例

* 创建实例后,会自动执行它的 onCreate() 方法
这个方法在 Application 类中是一个空方法

* 可以编写 Application 子类,
来将默认的 Application 类替换掉

* 应用启动时,要执行一些代码,
可以继承 Application 类,
重写它的 onCreate() 方法,
并在“清单文件”中配置

 


【data】 内部存储
内部存储 8个方法
================================================
/data/data/应用包名

getDir(String name, int mode)
--------------------------------
/data/data/应用/app_目录名

创建或访问文目录,返回 File 对象
在此目录可以创建任意文件、子目录

访问权限针对整个目录而不能针对单个文件

dataDir
--------------------------------
getApplicationContext().getApplicationInfo().dataDir + "/lib/libbd_etts_text.dat.so";
/data/data/com.baidu.tts.sample/lib/libbd_etts_text.dat.so

getFilesDir()
--------------------------------
/data/data/应用/files

获得表示 files 目录的 File 对象

getFileStreamPath(String name)
--------------------------------
/data/data/应用/files/文件名

获得表示 files 目录中,一个指定文件的 File 对象,
这些文件也可以通过以下方法创建流
openFileInput()
openFileOutput()

openFileInput(String name)
openFileOutput(String name, int mode)
--------------------------------
/data/data/应用/files/文件名

创建文件流

MODE_PRIVATE
MODE_APPEND
MODE_WORLD_READABLE
MODE_WORLD_WRITEABLE

deleteFile(String name)
--------------------------------
/data/data/应用/files/文件名

删除文件

fileList()
--------------------------------
/data/data/应用/files/

获得文件列表,返回文件名 String[] 数组

getCacheDir()
--------------------------------
/data/data/应用/cache/

获得缓存(临时)目录,返回表示该目录的 File 对象。
存储空间紧张时,系统会自动删除该目录中的文件。

你应该严格限制此目录总大小(例如1M),
超出限制时应对文件做清理

getDatabasePath("数据库文件.db")
例子:
tv=(TextView)findViewById(R.id.textView1 );
try {
//内部存储/data/data/tarena.day2304/app_mulu1
//还有一个/data/data/tarena.day2304/files
File mulu1dir= getDir("mulu1", MODE_PRIVATE); //创建目录
tv.setText(mulu1dir.getAbsolutePath()); //显示绝对路径 // /data/data/tarena.day2304/app_mulu1 //自动加前缀

File filesdir =getFilesDir(); //创建默认目录files
tv.append("\n"+filesdir.getAbsolutePath()); // /data/data/tarena.day2304/files

File f1 =getFileStreamPath("wenjian1"); //指向目标
f1.createNewFile(); //创建文件
tv.append("\n"+f1.getAbsolutePath()); // /data/data/tarena.day2304/files/wenjian1

FileOutputStream out =openFileOutput("wenjian2", MODE_PRIVATE);//创建文件,私人模式
out.write("abc".getBytes());
out.close();

FileInputStream in=openFileInput("wenjian2");
tv.append("\n"+in.read()); //97
tv.append("\n"+in.read()); //98
tv.append("\n"+in.read()); //99
in.close();
String[] list =fileList();
for(String s:list){
tv.append("\n"+s); //wenjian1 wenjian2
}
deleteFile("wenjian1");
tv.append("\n wenjian1已删除");

} catch (Exception e) {
Toast.makeText(this, "出错,清查看logcat日志异常信息", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}

 

【sdcard】 外部存储
================================================
Environment.getExternalStorageDirectory()

外部存储卡路径 File 对象

/mnt/sdcard
/storage/sdcard
/storage/sdcard0
/storage/sdcard1



-----------------------------------------------------------------------------------------
//mnt/sdcard/tlbs1503/apk
//mnt/sdcard/tlbs1503/image
//mnt/sdcard/tlbs1503/audio
public static final String SDCARD_ROOT=Environment.getExternalStorageDirectory().getAbsolutePath(); //+log.txt
public static final String APK_PATH=SDCARD_ROOT+"/tbls1503/apk";
public static final String IMAGE_PATH=SDCARD_ROOT+"/tbls1503/image";
public static final String AUDIO_PATH=SDCARD_ROOT+"/tbls1503/audio";
----------------------------------------------------------------

以前的Android(4.1之前的版本)中,SDcard跟路径通过“/sdcard”或者“/mnt/sdcard”来表示存储卡,而在Jelly Bean系统中修改为了“/storage/sdcard0”,以后可能还会有多个SDcard的情况。
目前为了保持和之前代码的兼容,sdcard路径做了link映射。 //http://blog.sina.com.cn/s/blog_5da93c8f0102vcam.html
为了使您的代码更加健壮并且能够兼容以后的Android版本和新的设备,请通过Environment.getExternalStorageDirectory().getPath()来获取sdcard路径,
如果您需要往sdcard中保存特定类型的内容,可以考虑使用
Environment.getExternalStoragePublicDirectory(String type)函数,该函数可以返回特定类型的目录,目前支持如下类型:
获得某种类型文件的标准存储目录,Environment.常量 // /mnt/sdcard/Movies
DIRECTORY_ALARMS //警报的铃声
DIRECTORY_DCIM //相机拍摄的图片和视频保存的位置
DIRECTORY_DOWNLOADS //下载文件保存的位置
DIRECTORY_MOVIES //电影保存的位置, 比如 通过google play下载的电影
DIRECTORY_MUSIC //音乐保存的位置
DIRECTORY_NOTIFICATIONS //通知音保存的位置
DIRECTORY_PICTURES //下载的图片保存的位置
DIRECTORY_PODCASTS //用于保存podcast(博客)的音频文件
DIRECTORY_RINGTONES //保存铃声的位置

 

 

getExternalCacheDir()//方法可以获取到 SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据//如果使用上面的方法,当你的应用在被用户卸载后,SDCard/Android/data/你的应用的包名/ 这个目录下的所有文件都会被删除,不会留下垃圾信息。
/sdcard/Android/data/应用/cache/

getExternalFilesDir(Environment.DIRECTORY_MUSIC) // 指向 /mnt/sdcard/Android/data/tarena.day2304/files/Music
Context.getExternalFilesDir()方法可以获取到 SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据//如果使用上面的方法,当你的应用在被用户卸载后,SDCard/Android/data/你的应用的包名/ 这个目录下的所有文件都会被删除,不会留下垃圾信息。
//比如APP的下载

Environment.getExternalStorageState()

获得存储卡状态代码,Environment.常量
MEDIA_BAD_REMOVAL 正确卸载前已经拔卡
MEDIA_CHECKING 正在检测
MEDIA_MOUNTED 正确装载,已准备好读写
MEDIA_MOUNTED_READ_ONLY 正确装载,只读
MEDIA_NOFS 正确装载,但不支持文件系统
MEDIA_REMOVED 已移除
MEDIA_SHARED 已经卸载并作为u盘连接电脑
MEDIA_UNMOUNTABLE 无法装载
MEDIA_UNMOUNTED 存在sd卡,但未装载


Environment.getRootDirectory() /system
Environment.getDataDirectory() /data
Environment.getDownloadCacheDirectory() /cache
例子:
File sdcard =Environment.getExternalStorageDirectory(); //指向 /mnt/sdcard/
tv.append("\n"+sdcard.getAbsolutePath());
File music =getExternalFilesDir(Environment.DIRECTORY_MUSIC); //指向 /mnt/sdcard/Android/data/tarena.day2304/files/Music
tv.append("\n"+music.getAbsolutePath());
File downloads=Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS); //指向 /mnt/sdcard/Download
tv.append("\n"+downloads.getAbsolutePath());
if(Environment.getExternalStorageState().equals( //如果外部的存储状态等于媒体就绪
Environment.MEDIA_MOUNTED)){
tv.append("\nsd卡可读写");
}



【SharedPreferences】 偏好设置
======================================================
/data/data/应用/shared_prefs/文件名.

p1 = getSharedPreferences(文件名, MODE_PRIVATE);

自定义文件名

p2 = getPreferences(MODE_PRIVATE);

Activity类名当做文件名
在一个 Activity 中,读写自己的偏好设置文件

p3 = PreferenceManager.getDefaultSharedPreferences(this);

包名当做文件名,
在整个应用中,都可以使用这个偏好设置文件

方法
--------------------------------------------------
edit()

contains(String key)
getAll()
getBoolean(String key, boolean defValue)
getFloat(String key, float defValue)
getInt(String key, int defValue)
getLong(String key, long defValue)
getString(String key, String defValue)
getStringSet(String key, Set<String> defValues)
registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener)
unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener)

SharedPreferences.Editor
--------------------------------------------------
putBoolean(String key, boolean value)
putFloat(String key, float value)
putInt(String key, int value)
putLong(String key, long value)
putString(String key, String value)
putStringSet(String key, Set<String> values)

remove(String key)
clear()

apply()
commit()

【StatFS】
==========================================
* 获得指定空间的空间使用情况

getBlockCount() 块的数量
getBlockSize() 块的大小
getFreeBlocks() 剩余块数量
getAvailableBlocks() 有权使用的剩余块数量

 



【终止】
BufferedReader的readLine()方法是在while((line=in.readLine())等于null){}时终止 //下标会向后移
read()是在while((n=in.read(buf))等于-1){}时终止

 

 

【把TextView控件中的数据输出到指定文件中去】 //gbk不行
byte[] ss =tv.getText().toString().getBytes("utf-8");
FileOutputStream outsd=new FileOutputStream("/sdcard/str",true);
outsd.write(ss);

byte[] ss =tv.getText().toString().getBytes("utf-8");
//String ss =tv.getText().toString();
FileOutputStream outsd=new FileOutputStream("/sdcard/str",true);
//BufferedWriter outsd =new BufferedWriter(new OutputStreamWriter(new FileOutputStream("/sdcard/str",true),"utf-8"));
// PrintWriter outsd=new PrintWriter
outsd.write(ss);

【单选】
当android:checkMark属性的值为?android:attr/listChoiceIndicatorSingle时选择模式为单选

 


【消息模型】
Message ; //消息对象
MessageQueue ; //消息队列
Looper; //迭代器 //隐藏线程进行迭代 可能是这个隐藏线程mThread = Thread.currentThread();
Handler //发送,处理消息

Day04-2 Android 中的线程应用(重点,难点)

【判断线程】 Log.i("TAG","---------------"+Thread.currentThread().getName());

1.Android 中线程对象应用机制?

1)所有的UI操作都在主线程(UI线程)执行.
2)所有的耗时操作都在工作线程(自己构建的)。

为什么?改善用户体验。

2.Android 中【线程通讯机制?】

假如在android中主线程要与工作线程之间实现数据的传递,那如何实现?

例如:
1)工作线程从网络中下载一个图片
2)主线程将下载的图片更新到页面上

关键是如何实现线程之间的无阻塞数据通讯?

3.Android中线程交互消息模型?

Android 中线程之间的交互通常是借助消息的传递实现,如何实现?

要理解其实现过程,首先要理解Android中消息模型四大核心对象。

1)Message (消息对象,数据的载体); //创建对象Message msg=Message.obtain();
2)MessageQueue(消息队列,存储多个消息)
3)Looper(迭代器,迭代消息队列)
4)Handler(发送,处理消息)

四大核心对象伪代码实现? //模拟

class Message{
Object obj;//借助此变量存储数据
......
}
class MessageQueue{
Message msg[]=new Message[10];
.....
}
class Looper{
MessageQueue mq;(关联消息队列)
public void loop(){//迭代
while(true){
.........
}
}
}
class Handler{//消息处理器
Looper looper;
public void sendMessage(msg){}
public void handleMessage(msg){}
}
程序=数据结构+算法

例如:大象放冰箱?

1)大象
2)冰箱

class Elephant{.......}
class IceBox{
Elephant e[]=new Element[3];
public void open(){}
public void put(Elephant e){}
public void close(){}
}

4.案例:工作线程发消息给主线程

数据结构:
1)主线程(UI线程,由JVM创建)
2)工作线程(由主线程创建)
3)消息(用于存储数据)
4)关联对象:MessageQueue,Looper,Handler

【算法实现】:

首先要掌握这样的一个核心思想:给哪个线程发消息,就获得与哪个线程的Looper相关联的Handler.-------------------------------》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

掌握:
1)主线程默认有Looper吗?
有,此Looper在主线程启动时,已创建,并关联的一个消息队列。

2)工作线程如何获得主线程的Looper?

Looper.getMainLooper();

3)工作线程中通过主线程的Looper构建Handler?

new Handler(Looper.getMainLooper());

4)Handler中借助sendMessage方法发送消息,借助handleMessage方法处理消息

sendMessage方法运行在哪个线程取决于在哪个线程。
handleMessage方法运行在哪个线程取决于handler关联的Looper.

5.案例:主线程给工作线程发消息?

例如:现有一个用户注册程序,主线程获得了页面上的数据以后将数据交给工作线程,
工作线程将数据写到网络中服务端。

数据结构:
1)主线程(UI线程,由JVM创建)
2)工作线程(由主线程创建)
3)消息(用于存储数据)
4)关联对象:MessageQueue,Looper,Handler


算法:
1)工作线程默认没有Looper
2)工作线程如何创建Looper




【Android 中线程应用】

1.Android 中线程应用机制?(两天)
2.Android 中线程之间的通讯模式?
借助消息传递,目的是为了尽量降低主线程(UI线程)的阻塞。

3.Android 中线程通讯消息模型?

1)Message
2)MessageQueue
3)Looper
4)Handler


【Handler】对象其它方法应用

1.sendMessage(msg)
2.handleMessage(msg)
3.sendEmptyMessage(int what)
4.postDelay(Runnable r); 底层发送延迟消息
.......
----------------------------------------------

【Message】 对象其它方法

1.obtain(); 首先从消息池获得消息,
消息池没有则创建。
Message msg=Message.obtain();
2.obtain(.....) 重载
3.sendToTarget(); 发送消息
Message.obtain(h,5).sendToTarget();
---------------------------------------------

记住:
1)给哪个线程发消息,就要获得与哪个线程的Looper相关联的Handler.
2)主线程默认有一个Looper,工作线程默认,需要时需要自己创建。

FAQ?

1)一个线程可以有多个Looper吗?不可以
2)一个Looper中只有一个消息队列?正确
3)一个线程可以有多个Handler对象吗?可以

----------------------------------------------

【HandlerThread】类的应用。 //构建一个工作线程

此类为Android中提供的一个工具类(本质上是一个线程类型,继承Thread),
借助此类主要是为了简化工作线程中Looper对象的创建。在此类中封装了
Looper对象的创建,获得,销毁过程。

例子:
package com.example.day04;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {
private Looper wLooper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**点击Button时主线程发消息给工作线程*/
HandlerThread ht;
public void onClick(View view){
//构建一个工作线程,并启动工作线程
ht=new HandlerThread("WorkThread");
ht.start();
//说明:一个线程只能有一个Looper
//1.假设此数据从页面上获得
String data="Hello Gsd1503!";
//2.将此数据传给工作线程
//2.1构建消息对象,封装数据
Message msg=new Message();
msg.obj=data;
//2.2构建Handler对象(关联工作线程的Looper)
//消息是要存储在工作线程的消息队列
Handler h=new Handler(ht.getLooper()){
public void handleMessage(
Message msg) {
Log.i("TAG", (String)msg.obj);
};
};
//2.3发送消息
h.sendMessage(msg);
}
/**当Activity销毁时会自动调用*/
@Override
protected void onDestroy() {
super.onDestroy();
//.......
ht.quit();
}
}

 


【runOnUiThread】
说明:在工作线程中更新UI可以调用runOnUiThread(Runnable r)方法
runOnUiThread(new Runnable() {
@Override
public void run() {
resultTv.setText("结果为:"+result);
}
});
--------------------------------------
Day05-6
【异步任务对象】(AsyncTask)

Android中提供了一个工具类,封装了消息的传递过程,此类为AsyncTask,
借助此类主要是为了简化Android消息传递过程代码编写。

此类中的有些方法运行在主线程,有些方法运行在工作线程,而且有一个先后的顺序。

【AsyncTask】 //新建一个子类,部分在主线程,部分在工作线程
package com.example.day05;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void onClick(View view){
//构建异步任务对象
DownTask task=new DownTask();
//启动异步任务(数据会传给doInBackGround方法)
task.execute("tarena","gsd1503");
}
//下面方法2的参数 //进度条 //下面2的返回值,下面3的参数
class DownTask extends AsyncTask<String,Void,String>{ //第一个字母大写
/**运行在主线程,通常用于执行一些初始化操作
* 执行的时间点,比doInBackground早*/
@Override
protected void onPreExecute() { //第一个执行
Log.i("TAG", "onPreExecute()");
}
/**此方法运行在工作线程*/
@Override
protected String doInBackground(String... params) { //第二个执行
Log.i("TAG", "doInBackground(..)");
return (params[0]+params[1])
.toUpperCase();
}
/**此方法运行在主线程
* 用于处理doInBackground方法的
* 返回结果
* */
@Override
protected void onPostExecute(String result) { //第三个执行
Log.i("TAG", "onPostExecute");
setTitle(result);
}
}
}

当我们构建异步任务类对象时,通常是构建AsyncTask的子类的对象,并重写doInBackGround方法,其它方法有选择性的重写。

掌握AsyncTask类中的常用方法:
1)onPreExecute()
2)doInBackground()
3)onPostExecute();
4)publishProgress()
5)onProgressUpdate()

 

【继承特性】:OOP(三大特性)

1)继承是对象共性的再次抽象。
可以将多个对象的共性提取到父类中,
以实现代码的复用。
2)继承的目的是实现代码的复用。
3)继承特性在实际应用中要掌握这样的
一个原则:子类除非要继承父类所有
的属性或方法,否则尽量不要使用继承。

class Rect{代表矩形
private int width;
private int height;
public void setWidth(int width){
this.width=width;
}
public void setHeight(int height){
this.height=height;
}
public int getArea(){
return width*height;
}
}
class Square extends Rect{ 正方形
}
class Test{
public static void main(String args[]){
Square s=new Square();
s.setWidth(100);
s.setHeight(300);
s.getArea();
}
}



【阻塞式队列】
package day05;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class TestBlocking {

public static void main(String[] args)
throws Exception{
//阻塞式队列,队列满了以后,不能继续再次放入数据
BlockingQueue<String> q01=
//new LinkedBlockingQueue<>(3);
new ArrayBlockingQueue<>(3);
q01.put("A");
q01.put("B");
q01.put("C");
System.out.println("q01="+q01);
//q01.put("D");//满了会阻塞
//q01.add("D");//满了会抛出异常
//System.out.println("q01=="+q01);
//取数据
System.out.println(q01.take());
System.out.println(q01.take());
System.out.println(q01.take());
//队列为空时take方法会等待
//System.out.println(q01.take());
//队列空时执行remove方法会抛出异常
//System.out.println(q01.remove());
}
}


【递增递减】
package day30;
import java.util.concurrent.atomic.AtomicInteger;
public class Test31 {
public static void main(String[] args) {
AtomicInteger at=new AtomicInteger(100);
System.out.println(at.getAndIncrement()); //100
System.out.println(at.getAndDecrement()); //101
System.out.println(at.getAndDecrement()); //100
System.out.println(at.getAndDecrement()); //99

}

}


【线程池】 //AsyncTask
储存在阻塞式队列 LinkedBlockingQueue
通过线程工厂创建 sThreadFactory
【任务execute】 //AsyncTask
储存在final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();


【webSocket】
webSocket, 是建立在socket基础上的,只不过是浏览器支持的,所以就叫websocket。是一个应用层协议,说的是,目前浏览器实现的一套通信协议,
用来解决之前HTTP,请求响应模型不合适的场合。
websocket是socket的简约实现,与socket相比,可以节省额外的端口占用,直接使用一个公网域名访问。另外协议对报文的流量消耗做了优化。

【socket】
socket是套接字,在你的语境下,多指传输层网络接口。

【XMPP】
XMPP,是一个应用层协议,协议基于 但是后来发现这种协议比较臃肿耗流量,而且对服务器要求比较高,所以就开始转向其他协议了,

 

-----------------------------------------------
Day06-2
【网络编程】(Socket编程)

1.何为Socket?

对于一个网络应用程序而言,网络客户端与网络服务端通过一个双向的连接通道进
行数据交互,这个双向的连接通道的一端称之为socket.

2.Socket 应用的构成?

1)Socket 服务端
2)Socket 客户端
3)Socket 通讯协议(标准,数据的载体):TCP/IP协议 //通讯协议类似于message的作用

3.Android 中Socket应用的构建步骤

1)编写Socket 服务端 (Java项目中编写)
ServerSocket server=
new ServerSocket(9999)
服务端对象构建以后,要在9999这个
端口进行监听。
while(true){
Socket socket=server.accept();监听,等待客户端的连接
}
2)编写Socket客户端(Android 项目实现)
构建客户端对象
Socket socket=new Socket();
连接服务端
socket.connect(new InetSocketAddress("172.16.7.17",9999),5000);//5000为等待时间
socket.connect(new InetSocketAddress(getResources().getString(R.string.ip),
Integer.parseInt(getResources().getString(R.string.port))),5000);

连接服务端时要制定IP,PORT;
IP:网络中计算机的唯一标识。
PORT:计算机中应用程序的唯一标识。

3)Socket客户端与服务端进行数据交互

客户端,服务端获得流对象?

当客户端向服务端写数据:借助输出流
当客户端从服务端读数据:借助输入流
当服务端读取客户端数据:借助输入流
当服务端向客户端写数据:借助输出流

具体方式:可以借助通道
socket.getInputStream();
socket.getOutputStream();
例子:
1)客户端给服务端写入消息
out=new DataOutputStream(socket.getOutputStream()); //输出流
out.writeUTF(params[0]+"/"+params[1]);
out.flush();
2)服务端读取客户端发过来的消息
in = new DataInputStream(socket.getInputStream()); //输入流
String s = in.readUTF();
3)服务端把读取的消息写入到服务器的文件中
out=new PrintWriter(new OutputStreamWriter(new FileOutputStream("d:\\dd.txt",true),"UTF-8"),true); //输出流
out.println(s+"/"+sdf.format(new Date()));

备注:android应用程序中通过socket访问网络时需要注意两点:
1) 添加访问网络的权限(AndroidManifest. android.permission.INTERNET
要加权限,倒数第四个第三项
<uses-permission android:name="android.permission.INTERNET"/>
2) 访问网络的动作在工作线程执行。

---------------------------------------------


 

Day07-1
【反射】
反射的应用(基础):了解
---------------------------------------------

1.FAQ?

1)Button,TextView等是对象吗? //是
这些对象是如何创建的?

2)Activity是对象吗?此对象是如何创建的? //是

这些对象都可以由底层框架(Framework)借助
反射构建.

2.何为反射?

反射是Java中的一种应用机制,主要应用于底层框架编程,是通用的编程的一种手段,
对应了一组API,借助这组API可以在对象运行时,获得其属性,方法等,并可以
通过某种手段改变属性的值,调用相关方法。

3.反射的作用?

1)简化代码的编写。
2)从底层操作对象。

3.反射应用的起点? //类对象的获取(类对象是反射的起点)

在Java应用中有两种对象:
类对象和类的对象


此类的类对象:Point.class,其类型为Class
此类的类的对象:new Point();其类型为Point
类对象在内存中只有一份,在类加载时构建。
类的对象在内存中可以有多份,一般通过new关键字构建。

类对象的获取方式:
1)类名.class
2)类的对象.getClass()
3)Class.forName("包名.类名");

4.通过类对象构建类的对象

1)调用类对象的newInstance方法
前提:此类必须有一个可访问的无参构造函数

Class.forName("").newInstance();

2)借助类对象获得构造方法对象,借助构造方法对象构建类的对象。

Constructor<?> c=c0.getDeclaredConstructor(String.class)
c0.getConstructors()
c0.getDeclaredConstructors();
Student s=(Student)c.newInstance("gsd1503");

例如


【通过类对象创建类的对象】 //通过构造方法对象创建类的对象 //通过类的对象创建类对象
package day0506;
import java.lang.reflect.Constructor;
class Point{
int x,y;
}
class Student{ //没有无参构造的要用类对象创建类的对象要用下面的第二种方法
private String s;
private Student(String s){
this.s=s;
}
@Override
public String toString() {
return " s=" + s;
}

}
//类对象的获取(类对象是反射的起点)
public class ReflectDemo {
public static void main(String[] args) throws Exception {
Point p1=new Point();//类的对象
Class<?> c1=Point.class; //类对象

Class<?> c2=p1.getClass();//获得类对象
Class<?> c3=Class.forName("day0506.Point");
System.out.println(c1==c2); //true
System.out.println(c2==c3); //true
creatObjectByClass();
}
private static void creatObjectByClass()throws Exception{
//第一种方法:
/* //类对象
Class<?> c0=Class.forName("day0506.Point");
//通过类对象创建类的对象
Object obj=c0.newInstance(); //Point类中必须包含无参的构造函数
System.out.println(obj); //day0506.Point@c17164
if(obj instanceof Point){
Point p=(Point)obj;
System.out.println(p); //day0506.Point@c17164
}*/

//第二种方法:
Class<?> c0=Class.forName("day0506.Student");
//通过类对象获得构造方法对象
//public Student(String s){}
//获得参数类型String类型的构造方法
Constructor<?> c=c0.getDeclaredConstructor(String.class);//Declared任意访问修饰符都可以

//假如构造方法私有化了,可以设置可
c.setAccessible(true);//设置可访问

//通过构造方法对象创建类的对象
Student s=(Student)c.newInstance("gsd1503");
System.out.println(s); // s=gsd1503
}
}

此类的类对象:Point.class,其类型为Class
此类的类的对象:new Point();其类型为Point


【建新按钮】 //MyButton
package com.example.day07;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Button;
public class MyButton extends Button{
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
}

 


5.通过类对象获得方法对象,执行方法对象?

Method m=c.getDeclaredMethod(Class<T> ...paramTypes)
c.getDeclaredMethods();

执行方法

m.invoke(类的对象,实际参数);

6.通过类对象获得类中的属性对象?

Field f=c.getDeclaredField(String name);
Field fs[]=c.getDeclaredFields()

//给属性赋值

f.set(类的对象,实际参数)

7.反射API总结

1)Class //类对象
2)Constructor //构造方法
3)Method //方法
4)Field //成员变量

 


【要跑到D盘】
进入D盘正确操作如下: // D:
cd是改变路径,一般在同一盘符下切换
cd\ 直接回到C 盘
cd/d D:\Java\test\src\test 跳出C盘,直接进入D:\Java\test\src\test

-------------------------------------------


Day07-2
【MySQL】 //数据库 本机IP地址172.16.4.165

1.MySQL 是什么?

1) 是一个软件(工具),数据库管理系统(DBMS)
2) 基于C/S架构(客户端,服务端)
3) 由MySQL AB 公司研发,现归甲骨文所有。
4) 开放平台(并非完全开源)

市场上类似产品:Oracle,DB2,SQLServer,....

2.MySQL 用于做什么?

1)更好的存储数据
2)更好的管理数据

3.MySQL 应用场合?

电子商务
网上银行
.......

4.MySQL 的安装的卸载?

4.1 安装 //确保系统内只有一个数据库软件mysql,如果已经有一个,把之前的删除掉

1) 解压到C盘根目录
C:\mysql-5.5.11-win32
2) 启动dos窗口(以管理员身份启动)
3) 切换到C:\mysql-5.5.11-win32\bin
3.1) 切换到根目录

cd / //cd \
3.2) 切换到mysql的bin目录

cd C:\mysql-5.5.11-win32\bin

4) 安装mysql 服务
mysqld -nt-install mysql

5) 启动mysql 服务
net start mysql

4.2 卸载

1) 先停服务
net stop mysql
2)卸载

在dos窗口的这个C:\mysql-5.5.11-win32\bin
目录执行
mysqld -remove mysql

5.MySQl登陆,退出 //mysql -u lipeineng -h 172.16.7.17 -p lpn
登入mysql
登陆: mysql -u root -p //mysql //给系统环境变量加一个C:\mysql-5.5.11-win32\bin;就可以直接用mysql登入,不然就必须进入到C:\mysql-5.5.11-win32\bin;目录下登入。
退出:\q // \c 回退 或 ctrl+c 退出

6.MySQL 常用操作

1)status (查看mysql状态信息)
2)show databases;(查看当前系统有哪些数据库)
3)select user();(查看当前登陆用户)
4)select now();(查看当前时间)
5)? functions;(查看系统函数,?等价于help)
6).....

7.MySQL 中的SQL? (重点)

SQL是一个标准,是客户端与服务端
进行数据交互的桥梁。

SQL分类:

1)DDL :数据定义语言(create,alter,drop,...)
2)DML: 数据操纵语言(insert,update,delete,select)
3)DCL : 数据控制语言(grant,revoke,commit,rollback)

-----------------------------------------------
Day07-3 MySQL中数据库的操作(DDL)

【数据库】(DataBase):存储数据一个仓库

1.创建数据库: create

语法: ? create database
例如:
create database tarena;
create database if not exists gsd1503 character set utf8;


查看当前用户有哪些数据库:
show databases;

查看数据库的创建过程:
show create database tarena;

2.修改数据库(alert)

语法: ? alter database
例如:修改数据库的编码
alter database tarena character set utf8;

3.删除数据库 //删数据库
语法: ? drop database

例如:
drop database tarena;
drop database if exists gsd1503;

4.打开数据库

当使用数据库之前需要先打开数据

use 数据库名

例如: use tarena;

查看当前正在使用的数据库:
select database();
----------------------------------------------
Day07-4 数据库中表的操作(DDL)

【表】(Table)是数据库中的最基本存储单元,
由行和列组成,通常将行理解为记录,将
列理解为字段或数据项。

1.【表的创建】

语法: ? create table

create table 表名(
列名 类型 [约束] [默认值],...);

例如:
创建表之前先打开数据库: use tarena;

create table employee(
id int primary key, //id就是key值,方便查找
name varchar(100) not null,
gender enum('M','F') default 'M',
salary decimal(10,2), //10表示总位数 //2表示小数位数
email varchar(50) unique,
birthday datetime not null
);

主键: 为key //用来寻找定位
1)表中的一个或多个字段
2)它的值不允许为空,且必须唯一。
3)借助primary key 修饰

【查看】 //查询数据库 //查看数据库
查看当前用户有哪些数据库: show databases;
查看数据库的创建过程:show create database tarena;
当使用数据库之前需要先打开数据库:use 数据库名
查看当前正在使用的数据库:select database();
查看当前数据库的表: show tables;
显示表结构: desc employee;
简单查询表中数据: select * from customer; //select * from customer where id>0;
查询所有的用户 use mysql // select * from user;
//select Host,User,Password from user;
返回 \c

创建表时常用类型:

1) 整数类型(int,bigint,...)
2) 浮点类型(decimal,numeric,...)
3) 字符类型(char,varchar)
4) 日期类型(date,datetime,timestamp,...)
5) 其它(enum,set,blob,....)

创建表时常用约束:

1) 主键约束(primary key) // 为key //用来寻找定位 //1)表中的一个或多个字段 2)它的值不允许为空,且必须唯一。 3)借助primary key 修饰
2) 非空约束(not null) //不能为空
3) 唯一约束(unique) //可以没有但有的话必须唯一
4) 外键约束(先不讲)

例如:
create table product1(
id bigint auto_increment,
price numeric(10,2) default 0,
sex enum('M','Y','N') default 'N',
primary key (id)
) engine=InnoDB character set utf8;
//engine=InnoDB是引擎

auto_increment 表示此字段的值是可以递增的 //自增


2.【表的修改】(了解): alter

例如,现有一张表
create table student( id int primary key);
1) 向表中添加一个字段
alter table student add name varchar(20) not null;

alter table customer modify birthday date not null;
2) 修改表中字段name为lastName
alter table student change name lastName varchar(20) not null;
3) 修改表中字段lastName的类型为varchar(100)
alter table student modify lastName varchar(100) not null;

alter table customer modify money decimal(7,2) not null;
4) 删除表中的列(字段)
alter table student drop lastName;


3.【删除表】 drop //删表

语法: ? drop table

例如: drop table student;
----------------------------------------------
Day07-5 表中数据的操作(DML)
以如下表为例:
create table customer(
id int primary key auto_increment,
name varchar(100) not null,
phone varchar(20) not null unique,
email varchar(50) unique
);

1.【向表中写入数据】(insert)

insert into customer(id,name,phone,email)
values (null,'A','139','A@t.com');

insert into customer
values (null,'B','138','B@t.com');

insert into customer
values ('A','139','A@t.com'); 错误

insert into customer(id,name,email)
values (null,'B','A@t.com');错误 phone必须给值

insert into customer(id,name,phone)
values (null,'B','133');
同时插入多条数据
insert into customer values
(null,'E','133','E@t.com'),
(null,'F','139','F0t@t.com');


insert into customer values
(12,'E','133','E@t.com',400.154),
(13,'F','139','F@12t.com',100.12315);

2.【修改表中数据】(update)
update customer set name='AA' where id=1;

update customer set money=131215.12654 where id=1259;

update customer set name='AA',email='AA@t.com'
where id=1;

3.【删除表中数据】(delete) //删数据

delete from customer where id=1;
delete from customer where email is null;

delete from customer;

4.【简单查询表中数据】(select)
select * from customer;

--------------------------------------------


mysql的编码设置
set character_set_filesystem=utf8;
set character_set_server=utf8;
set character_set_client=utf8;


【连接数据库】 //mysql -u lipeineng -h 172.16.7.17 -p 369
package util;
public class Config {
public static final String DRIVER="com.mysql.jdbc.Driver";
public static final String URL="jdbc:mysql://172.16.7.17:3306/test";
public static final String USER="lipeineng";
public static final String PWD="369";
}

package util;
import java.sql.Connection;
import java.sql.DriverManager;
public class JDBCUtil {
public static Connection getConnection()
throws Exception{
Class.forName(Config.DRIVER);
return DriverManager.getConnection(
Config.URL,Config.USER, Config.PWD);
}
}

Day10-5 MySQL 中的用户管理?(了解)
【创建用户】
1.创建用户?(具备创建用户的权限) //新建用户

1)本机用户(装有数据库的这台计算机登陆)

create user 'tarena'@'localhost'
identified by 'tarena123'; //tarena123是密码

此用户创建以后会存储在user表中。

登陆: mysql -u tarena -h localhost -p

2)远程用户(可以在其它机器上访问本机数据库)

create user 'gsd1503'@'%'
identified by 'gsd1503';

登陆:
mysql -u gsd1503 -h 172.16.7.17 -p

2.给用户权限?(通过root用户登陆)
grant all on hr.* to 'gsd1503'@'%';

3.撤销权限?(通过root用户登陆)
revoke all on hr.* from 'gsd1503'@'%';

4.删除用户?(通过root用户登陆)
drop user 'gsd1503'@'%';

5.设置root的密码 //除了创建时可以连用户名加密码一起创建外,也可以后面加密码
用root进入mysql后
方法一:
mysql>set password=password('你的密码');
mysql>flush privileges; //没测试过

方法二:
mysql>grant all on *.* to 'root'@'localhost' identified by '你的密码' with grant option;
mysql>flush privileges; //没测试过

方法三:
mysql>use mysql;
mysql>update user set password=password('你的密码')where user='root';
mysql>flush privileges; //可以用来改其他用户名的密码

 


----------------------------------------------
Day10-6 MySQL 其它客户端应用(了解)

1.Eclipse
2.MySQL Front //Host 填localhost
3.........
-----------------------------------------------

【eclipse】
eclipse快捷键失效错误;
原来是在eclipse的文本编辑器下的文本编辑模式,诶,改过来啦,到eclipse的java编辑模式,一切O了!在网上查了半天,都没搞定的问题就是这么细致的一个错误...

 

------------------------------------------------
【事务操作】
Day09-2 MySQL 中的事务操作

1.何为事务(Transaction)?

1)事务是一个不可分割的逻辑业务。
2)此业务中的所有操作是捆绑在一起的。
3)这些操作在执行时要么都成功要么都失败。

2.事务的作用?
保证操作的原子性,一致性,隔离性,持久性。
即事务的四大特性:ACID

1)原子性:不可分割性,例如转账操作。
2)一致性:操作前后数据是一致的。(例如取钱)
3)隔离性:事务之间互不影响。
4)持久性:事务一旦提交可以持久性保存在数据库

3.MySQL中的事务操作?

MySQL默认事务控制是自动提交方式,当执行
完一个DML语句以后事务会自动提交。

MySQL中的事务控制语句:

开启事务:
set autocommit=0;
其中0表示手动控制事务,默认为1;

insert ...
update....

提交事务(提交以后会自动结束)
commit;

当需要撤销某个事务时,不是执行commit,
而是执行rollback(回滚),但无论是commit,
还是rollback整个事务都会结束。


set autocommit=0;

insert ...
insert ....

rollback; (回滚,撤销事务,这两个insert都不会
写到数据库)

当需要撤销一部分操作时,通常要在
事务中设置回滚点

set autocommit=0; (off)与其对应的就是on

insert 1
insert 2

savepoint p1; (回滚点)

insert 3,
insert 4

rollback to p1; (撤销insert3,4操作)

commit; (insert 1,insert2 会写到数据库)


在实际应用中事务与业务紧密联系在一起,
事务的控制应该在程序业务层。
-----------------------------------------------

 

【表的设计】
Day09-3 表的设计(重点,难点,了解)

1.表的设计关系
2.表的设计范式

-----------------------------------------------
Day09-4 表的关系设计

在实际应用中表关系通常有如下三种设计:
1)one2many
2)one2one
3)many2many

1.
【one2many】 (一对多)

1) 一个用户有多个订单。
2) 一个部门可以有很多雇员。
3) 一个国家可以有很多省份。

这样的关系在表中如何实现?

例如:部门和雇员

create table department(
id int primary key auto_increment,
name varchar(100) not null
);
create table employee(
id int primary key auto_increment,
name varchar(100) not null,
salary int default 0,
dept_id int
);
关系的建立:

alter table employee
add foreign key(dept_id)
references department(id);

通常将这样的一个字段称之为外键.
外键:
1)表中的一个或多个字段
2)它的类型,值参考关系中主键的类型和值

向表中写入数据:

insert department values (null,'A');
insert department values (null,'B');
insert employee values (null,'EA',100,1);
insert employee values (null,'EB',100,2);
insert employee values (null,'EC',100,1);
insert employee values (null,'EC',100,3); 错的,没有3

当删除department表中数据时应首先将关系表Employee中相关联的记录的
外键设置为null,或者先删除关联记录。

update employee set dept_id=null
where dept_id=1;
delete from department where id=1;

假如想删除部门表,需要先删除关系表
Employee中的外键约束

alter table employee
drop foreign key 约束名;

约束名可以采用
show create table employee
方式查看

当删除"部门表"中数据时级联删除关系表"雇员表"中关联数据,添加 //删除用的少;
外键约束时,可以采用如下方式:

alter table employee
add foreign key (dept_id)
references department(id)
on delete cascade;

当删除"部门表"中数据时级联置空关系表"雇员表"中外键的值,添加 //设置为null用的比较多
外键约束时,可以采用如下方式:

alter table employee
add foreign key (dept_id)
references department(id)
on delete set null;

总结:对于one2many关系的实现通常要在
many的一端添加一个外键(FK).


2.
【one2one】 关系

一个公司只能发行一种类型股票
在达内一个学生一台电脑
.....................

one2one是一个特殊的one2many
我们只要限制one2many中的many
将其添加一个唯一约束就可以了

例如

create table company(
id int primary key,
name varchar(100) not null
);
create table stock(
id int primary key,
code varchar(50) not null unique,
cid int unique
);
alter table stock add foreign key (cid)
references company (id);

对于one2one的实现通常是:FK+UK

对于one2one关系的实现,外键设置在
哪一端取决于具体业务。

例如:在达内一个学生(student)
一台电脑(Computer).

create table student(
id int primary key,
name varchar(20)
);
create table computer(
id int primary key,
code varchar(20),
sid int unique
);
alter table computer add foreign key(sid)
references student (id);

3.
【Many2Many】 (多对多)

老师<-->学生
学生<-->课程
角色<-->权限

对于多对多的实现通常要借助中间表实现

学生课程关系:

create table student(
phone varchar(20) primary key,
name varchar(20) not null
);
create table course(
id int primary key,
name varchar(30) not null
);
借助中间表实现关系
create table scoretab(
sid varchar(20),
cid int,
score int,
primary key (sid,cid)
);
复合主键:由多个字段组成,其值的组合不能出现重复。

添加外键约束:
alter table scoretab add foreign key (sid)
references student (phone);

alter table scoretab add foreign key (cid)
references course (id);

总结表关系实现:
1)one2many: FK
2)one2one: FK+UK
3)many2many: 中间表

----------------------------------------------

----------------------------------------------
Day09-4 表的设计范式(重点,难点,了解)

所谓范式一般指的是设计表的应遵循的一些规则

第一范式:属性(字段)不可再分;
例如
create table employee(
id int primary key,
name varchar(200) not null,
phone varchar(20) not null
);
假如phone表示公司电话,自己手机号,以上表的设计就不满足第一范式。
create table employee(
id int primary key,
name varchar(200) not null,
jobPhone varchar(20),
myPhone varchar(20) not null
);
第二范式:非主属性不能部分依赖主属性(字段)
例如:成绩表
create table scoretab(
sid int,
cid int,
score int,
cname varchar(100),
primary key (sid,cid)
);
以上表的设计是否满足第二范式?不满足,
cname(课程名)依赖于CID(课程ID)但不依赖于SID(学生id),应该将cname放到课程表。

第三范式:非主属性不能依赖于非主属性

例如:学生表
create table student(
id int primary key,
name varchar(100) not null,
schoolName varchar(200) not null,
schoolPhone varchar(20) not null
);
以上表是否满足第三范式的设计?不满足
存在非主属性schoolPhone依赖于非主属性schoolName.修改如下:

create table student(
id int primary key,
name varchar(100) not null,
schoolId int
);
create table school(
id int primary key
schoolName varchar(200) not null,
schoolPhone varchar(20) not null
);

alter table student
add foreign key(schoolId)
references school(id)
----------------------------------------------
Day09-5 深入MySQL中的查询(重点)

准备工作:导入一些表和数据

source d:\hr_mysql.sql

以上语句表示执行某个sql文件中的sql语句

MySQL 中的查询类型:

1) 基本查询
2) 限制查询
3) 排序查询
4) 分组查询
5) 嵌套查询
6) 多表查询
---------------------------------------------
Day09-1 SQL查询(简单查询)

1.查询当前日期?
select now();
其中now()为系统函数

2.查询当前登陆用户?
select user();
3.查询当前正在使用的数据库?
select database();

查看系统函数的方式: ? functions

4.查询部门表中所有部门信息?

select * from departments;
其中"*"代表所有列。

5.查询部门表中的部门id,部门名称?

select id,department_name
from departments;

6.查询雇员的名字,薪水,入职日期?
select first_name as name,salary,hire_date
from employees;

其中"name"为first_name的别名,"as"可以省略

7. 查询每个雇员的薪水加300的值?

select employee_id,salary+300
from employees;

8. 查询所有人的薪水总和?
select sum(salary) from employees;
其中sum函数用于求和

9.查询公司总计有多少雇员
select count(*) from employees;
其中count函数用于统计个数。

10.查询所有雇员的平均薪水?
select avg(salary)
from employees;
其中"avg"函数表示求平均薪水

11.查询雇员的最高和最低薪水?
select max(salary),min(salary)
from employees;
---------------------------------------------
Day09-2 SQL查询(限制查询)

1.查询薪水大于10000的雇员的名字?

select first_name,salary
from employees
where salary>10000;

2.查询薪水大于等于10000
小于等于20000的雇员的名字,薪水?

select first_name,salary
from employees
where salary>=10000&&salary<=20000;

或者

select first_name,salary
from employees
where salary between 10000 and 20000;

3.查询薪水等于10000或者
等于20000的雇员的名字,薪水?

select first_name,salary
from employees
where salary=10000||salary=20000;

或者

select first_name,salary
from employees
where salary in (10000,20000,30000);

4.查询1999年入职的雇员的名字,入职日期?

select first_name,hire_date
from employees
where year(hire_date)='1999';

或者

select first_name,hire_date
from employees
where hire_date like '1999%';

其中"%"代表任意的0个或多个字符

5.查询名字中第二个字母为A的雇员的名字

select first_name,hire_date
from employees
where first_name like '_a%';

其中"_"代表任意的一个字符。

6.查询提成为null的雇员的名字,薪水?

select first_name,salary
from employees
where commission_pct is null;

7.查询提成不为null的雇员的名字,薪水?

select first_name,salary
from employees
where commission_pct is not null;

8.查询雇员表中前5条记录中的雇员名字和薪水。

select first_name,salary
from employees
limit 5;

9.查询雇员表中第3条到第5条记录中的
雇员名字和薪水。

select first_name,salary
from employees
limit 2,3;

表示从>2开始取,取3条

假设现有10条记录,每页最多显示3条,
总计可以分为4页,现取第三页:

select first_name,salary
from employees
limit 6,3;

以上这个语句经常用于分页查询

总页数的计算方法:
10%3==0?10/3:10/3+1

总结:
where 子句用于设置查询条件,一定
要写在from子句之后,
“limit”子句用于限制返回的记录函数,
假如出现limit要放在所有子句最后。

10.练习

1) 查询2000年入职的员工的人数?
select year(hire_date),count(*)
from employees
where year(hire_date)='2000';
2) 计算2月份入职的员工的薪水总和?
select month(hire_date), sum(salary)
from employees
where month(hire_date)='02';

或者

select month(hire_date), sum(salary)
from employees
where hire_date like '%-02-%';

查函数: ? functions

3) 显示佣金为空的前5条记录中的
雇员名字,入职日期,佣金?

select first_name,hire_date,commission_pct
from employees
where commission_pct is null
limit 5;
----------------------------------------------
Day09-3 排序查询(order by , asc|desc)

1.按入职日期升序显示雇员的名字和薪水,入职日期相同,则薪水降序排序。

select first_name,hire_date,salary
from employees
order by hire_date asc,salary desc;

其中"asc"表示升序(可以省略),"desc"表示降序。

或者

select first_name,hire_date,salary
from employees
order by 2,3 desc
limit 10;

其中"2"和"3"表示select列表中列的序号

对于order by子句的应用上,假如没有limit子句,它放在所有子句的最后,
且是最后执行。

2. 查询雇员的薪水加300以后的值,并新的薪水降序排序。

select first_name,salary+300 newSalary
from employees
order by newSalary desc;

-----------------------------------------------

Day09-4 分组查询 (group by ,having)

1.求每个部门的平均薪水?
select department_id,avg(salary)
from employees
where department_id is not null
group by department_id;
其中"group"子句用于分组

2.求每个工种的人数?
select job_id,count(*)
from employees
group by job_id;

3.求每年入职的人数?

select year(hire_date),count(*)
from employees
group by year(hire_date);

4.求部门薪水总和大于50000的部门
id和薪水总和,并按总和薪水降序排序。

select department_id,sum(salary)
from employees
where department_id is not null
group by department_id
having sum(salary)>50000
order by 2 desc;

其中"having"子句用于限制分组以后的
结果。

5.求每个部门的薪水总和,平均薪水,最大
薪水,最小薪水,人数。

select department_id,sum(salary),
avg(salary),
max(salary),min(salary),count(*)
from employees
where department_id is not null
group by department_id;
-----------------------------------------------
作业
1.总结表的设计,查询
2.实践练习?

1) 查询工种的人数,平均工资。
2) 查询1999年2月份入职的员工的名字,薪水,
并按降序排序。
3) 求平均薪水最高的那个部门的部门id?
4) 求佣金不为空的雇员的名字薪水,按佣金
降序排序。

3.预习嵌套查询,多表查询。
----------------------------------------------

 

 

Day10-2 MySQL 查询(嵌套查询)

【嵌套查询】
1.查询比雇员201的薪水还要高的雇员编号,
薪水。

select employee_id,salary
from employees
where salary>(
select salary
from employees
where employee_id=201);

2.求比部门50平均薪水还要高的部门平均薪水?

select department_id,avg(salary)
from employees
where department_id is not null
group by department_id
having avg(salary)>(
select avg(salary)
from employees
where department_id=50);

--------------------------------------------
Day10-3 MySQL 查询(多表查询)

当我们需要的数据来自多张表时可以执行
多表查询。

1.求雇员201所在的部门的部门名称?

select employee_id,e.department_id,department_name
from employees e,departments d
where e.department_id=d.department_id
and e.employee_id=201;

或者

select employee_id,e.department_id,department_name
from employees e inner join departments d
on e.department_id=d.department_id
where e.employee_id=201;

其中"inner join"表示内连接,"inner"可以省略,
on后写连接条件。

2.求雇员201所在的部门的部门名称,以及这个
部门所在城市?

select employee_id,e.department_id,department_name,city
from employees e join departments d join locations l
on e.department_id=d.department_id and
d.location_id=l.location_id
where e.employee_id=201;

3.求比本部门平均薪水还要高的雇员名字,薪水。

select first_name, e1.department_id,salary
from employees e1 join
(select department_id,avg(salary) avg_sal
from employees
where department_id is not null
group by department_id)e2
on e1.department_id=e2.department_id
where e1.salary>e2.avg_sal;

当需要将子查询看成是一张表时,一定要给
这个表起个别名。

select first_name, e1.department_id,salary
from employees e1
where e1.salary>(
select avg(salary)
from employees e2
where e2.department_id=
e1.department_id
);

4.查询每个雇员及这个雇员所在的部门信息?

select employee_id,e.department_id,department_name
from employees e left outer join departments d
on e.department_id=d.department_id

其中"left outer join"表示左外连接,outer
可以省略,对于左边表而言,满足on条件的
要显示,不满足on条件的也要显示。

5.查询每个部门及这个部门的雇员信息?

select employee_id,e.department_id,department_name
from employees e right outer join departments d
on e.department_id=d.department_id

其中"right outer join"表示右外连接,outer
可以省略,对于右边表而言,满足on条件的
要显示,不满足on条件的也要显示。

6.笛卡尔积

select employee_id,department_name
from employees,departments

通长可以借助此数据作为测试用。

create table mytemp
as
select employee_id,department_name
from employees,departments;

-------------------------------------------
Day10-4 MySQL 中的视图(了解)

【视图(View)】
1.视图(View)是什么?
1)数据库中的一个对象
2)虚拟的表(基于表构建,但不存储数据)
3)对外的窗口

2.视图的作用?

1)提高系统数据的安全。
2)简化程序中SQL语句的编写。

3.视图的创建

应用1:
create view empv2
as
select first_name,salary
from employees;

执行查询 : select * from empv2;

应用2:视图创建以后存储在数据库中

create view empv3
as
select department_id,avg(salary) avg_sal
from employees
group by department_id;

执行如下查询:

select first_name, e1.department_id,salary
from employees e1 join empv3 e2
on e1.department_id=e2.department_id
where e1.salary>e2.avg_sal;

3.视图的删除

drop view empv2;
----------------------------------------------
Day10-5 MySQL 中的索引(了解)

【索引(index)】
1.何为索引?(index)

假如将一张表理解为一本书,那么书的大纲就
是表中的索引。

2.使用索引的目的?

提高查询的速度。

3.何时使用索引?

1)经常查询表中数据时,以某个字段作为查询条件。
例如: select employee_id salary
from employees where first_name like '%A%'
2)表中数据量比较大,而我们需要的数据非常
少时。

4.索引的创建?
create index fname on employees(first_name);
索引创建以后在查询时假如查询条件中
使用到了first_name,此时会自动使用索
引。

5.索引的删除?
drop index fname on employees;
----------------------------------------------

Day10-5 JDBC 基础

1.JDBC 是什么?

【JDBC】
1) Java DataBase Connectivity
2) 一组访问数据库的标准(API)

2.JDBC 的作用?

在Java应用程序中访问数据库

3.JDBC 的应用架构?

Java应用
-------------
JDBC (API)
|--->面向Java程序员(标准,java.sql.*)
|--->面向数据库厂商(驱动程序)
--------------
MySQL,Oracle,DB2,...

4. JDBC 应用的构建步骤

1) 加载驱动程序(由厂商提供)
2) 建立连接(借助驱动程序)
3) 创建Statement(借助此对象发送SQL)
4) 发送SQL
5) 处理结果
6) 释放资源(先打开的后关闭)

5.JDBC 中CRUD操作的实现?

1)添加记录(C)
2)查询记录(R)
3)更新记录(U)
4)删除记录(D)

6.JDBC中PreparedStatement对象的应用

PreparedStatement继承Statement,
此接口的对象支持在SQL语句中使用
占位符"?"(代替SQL语句中的某字段的个值)
借助此Statement主要是为了简化SQL
语句的编写,防止SQL注入,提高系统安全。

说明:假如在sql语句中需要动态传值,建
议使用PreparedStatement.

7.JDBC 中常用API?

1)DriverManager
2)Connection
3)Statement (execute,executeUpdate,executeQuery)
4)PreparedStatement
5)ResultSet //类型与Cursor相似
6).......

8.JDBC中连接对象的封装

1)对重复编写代码进行提取,以简化代码编写。
2)提高代码的可维护性性。
----------------------------------------------
作业
1.总结
2.改写留言本,将数据写到服务端的数据库中。
3.尝试一个在activity直接访问mysql数据库的
案例。
-----------------------------------------------

 


import static util.Config.*; //导入静态的

 

-----------------------------------------------
Day11-2 JDBC 进阶 //JDBCmysql

1.JDBC 操作数据库中的Blob字段 【修改mysql编码方式】

在数据库中可以借助Blob类型的字段存储二进制数据。

1).停止mysql 服务 : net stop mysql
2).修改mysql配置文件: my.ini
将其编码方式改为utf8;

default-character-set=utf8
character-set-server=utf8

3).重启服务: net start mysql
4).检测编码: 登陆mysql以后status
5).在数据库中创建表:(保证数据库和表的编码都是utf8)
use test;
create table imgtab(
id int primary key,
img longblob
)character set utf8;

2.Jdbc中元数据?

描述数据的数据。

<name>张杰</name>

其中:
张杰称之为数据
name为描述数据的标签:元数据


id name salary (元数据)
10 A 100000 (数据)

在JDBC中元数据对象:

1)DatabaseMetaData (通过Connection获得)
2)ResultSetMetaData (通过ResultSet获得)

借助元数据可以实现通用编程

-----------------------------------------------
作业
1.总结
2.完成Blob字段的读取
3.了解元数据的应用
4.预习Android中SQLite的应用

 

【SQLite】
Day12-1 SQLite数据在Android中的应用
---------------------------------------------
1.SQLite 是什么?

1) DBMS (数据库管理系统)
2) 开源(轻量级)
3) 没有独立的进程,需要工作在用户进程
4) 无需启动服务
5) 通常应用在移动式电子设备中

2.SQLite 在Android中的应用?

例如:联系人信息,记事本(便签)

如何使用Android中的SQLite数据库?

SQLite存储是Android内部存储的一种实现方式。

在Android中要从底层操作SQLite需要借助adb桥先进入Linux系统。

SQLite 需要配置环境变量 Path //D:\Android\sdk\platform-tools;

db.execSQL("CREATE TABLE IF NOT EXISTS milestone(id INTEGER PRIMARY KEY AUTOINCREMENT, distance INTEGER,
longitude DOUBLE, latitude DOUBLE,startlongitude DOUBLE,startlatitude DOUBLE,
orderStartTime DATETIME,orderEndTime DATETIME, //时间 就是以字符串的格式存入
orderID varchar(20) )");

SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date nowTime1 = new Date(System.currentTimeMillis());
String startTime = sdFormatter.format(nowTime1);

【功能】
adb shell (进入linux系统) //要先开安卓虚拟机
ls (显示linux系统当前的目录结构)
cd (切换到某个目录)
.exit(退出linux系统)

在android 系统目录中借助SQLite3命令创建SQLite数据库

cd data/data/com.example.day051302.databases //记得进入databases数据库目录 //要分开一步一步进

【创建或打开数据库】
sqlite3 test.db (创建或打开test.db数据库)

【显示所有的表】
.tables //显示所有的表

【新建表】
create table test01(
id integer primary key,
content varchar(100));

【插入数据到表中】
insert into test01 values (1,'CA');
insert into note values (20,'CA','2015-5-16 08:16:50');
db.insert("note",null, values);
【查询表中的数据】
select * from test01;
db.query("userpeople", new String[]{"phone","password"}, "phone=?", new String[]{phoneEt}, null, null, null);
query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);
public Cursor queryWhere(String content){ // ? 用字符串数组表示,比如new String[]{"%"+content+"%"} //【问号】
//打开数据库
db=dbHelper.getReadableDatabase();
//执行查询
String sql= "select _id,content,noteDate from note " + "where content like ? order by noteDate desc ";
return db.rawQuery(sql, new String[]{"%"+content+"%"});
}

//Uri dataUri=Uri.parse("content://com.android.contacts/data");
Uri dataUri=Data.CONTENT_URI;
String[] cols=new String[]{
Data._ID, //0
Data.MIMETYPE, //1
Data.RAW_CONTACT_ID, //2
Data.DATA1, //3
Data.DATA15 //4
};
Cursor c2=r.query(dataUri, cols, Data.RAW_CONTACT_ID+"="+id, null, null);
public final Cursor query(Uri uri, String[] projection,String selection, String[] selectionArgs, String sortOrder)

【Uri】
[scheme:]scheme-specific-part[#fragment]
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]

http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic

scheme: 匹对上面的两个Uri标准形式,很容易看出在:前的部分是scheme,所以这个Uri字符串的sheme是:http
scheme-specific-part: 很容易看出scheme-specific-part是包含在scheme和fragment之间的部分,也就是包括第二部分的[//authority][path][?query]这几个小部分,所在这个Uri字符串的scheme-specific-part是://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4 ,注意要带上//,因为除了[scheme:]和[#fragment]部分全部都是scheme-specific-part,当然包括最前面的//;
fragment: 这个是更容易看出的,因为在最后用#分隔的部分就是fragment,所以这个Uri的fragment是:harvic
下面就是对scheme-specific-part进行拆分了;
scheme-specific-part中, 最前端的部分就是authority,?后面的部分是query,中间的部分就是path
authority: 很容易看出scheme-specific-part最新端的部分是:www.java2s.com:8080
query: 在scheme-specific-part中,?后的部分为:stove=10&path=32&id=4
path: 在**query:**在scheme-specific-part中,除了authority和query其余都是path的部分:/yourpath/fileName.htm
又由于authority又一步可以划分为host:port形式,其中host:port用冒号分隔,冒号前的是host,冒号后的是port,所以:
host: www.java2s.com
port: 8080

代码提取
getScheme() :获取Uri中的scheme字符串部分,在这里即,http
getSchemeSpecificPart():获取Uri中的scheme-specific-part:部分,这里是://www.java2s.com:8080/yourpath/fileName.htm?
getFragment():获取Uri中的Fragment部分,即harvic
getAuthority():获取Uri中Authority部分,即www.java2s.com:8080
getPath():获取Uri中path部分,即/yourpath/fileName.htm
getQuery():获取Uri中的query部分,即stove=10&path=32&id=4
getHost():获取Authority中的Host字符串,即www.java2s.com
getPost():获取Authority中的Port字符串,即8080

另外还有两个常用的:
List< String> getPathSegments():上面我们的getPath()是把path部分整个获取下来:/yourpath/fileName.htm,getPathSegments()的作用就是依次提取出Path的各个部分的字符串,以字符串数组的形式输出。以上面的Uri为例:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#harvic";
Uri mUri = Uri.parse(mUriStr);
List<String> pathSegList = mUri.getPathSegments();
for (String pathItem:pathSegList){
Log.d("qijian","pathSegItem:"+pathItem);
}
打出来的列表为:
pathSegItem:yourpath
pathSegItem:fileName.htm

getQueryParameter(String key):在上面我们通过getQuery()获取整个query字段:stove=10&path=32&id=4,getQueryParameter(String key)作用就是通过传进去path中某个Key的字符串,返回他对应的值。
[java] view plaincopy在CODE上查看代码片派生到我的代码片
String mUriStr = "http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id#harvic";
mUri = Uri.parse(mUriStr);
Log.d(tag,"getQueryParameter(\"stove\"):"+mUri.getQueryParameter("stove"));
Log.d(tag,"getQueryParameter(\"id\"):"+mUri.getQueryParameter("id"));
注意注意,我稍微更改了下字符串,把query中id的值去掉了!!!!!然后看看通过getQueryParameter("id")获取它的值会得到什么!
结果如下:
getQueryParameter("stove"):10
getQueryParameter("id"):
可以看到,在path中,即使针对某一个KEY不对它赋值是允许的,但在利用getQueryParameter()获取该KEY对应的值时,获取到的是null;

 

 

 

 

 


【退出】
.exit(退出SQLite)

SQLite
【删除数据库】
在安卓中 //主体中
this.deleteDatabase("lipei.db");
在安卓中 //不在主体内,要有context才行
context.deleteDatabase("neng.db");
在dos命令中 //不要进入(sqlite3 test.db)数据库内,在数据库外进行删除 cd data/data/com.example.day051302.databases
rm ****.db

【查表结构】
pragma table_info('note'); //note是表的名字

【修改表中数据】
通用方法
db.execSQL(" update note set _id=4 where _id=12");
专用
db.update("note", cv, "_id=?", new String[]{"2"});
源代码
update(String table, ContentValues values, String whereClause, String[] whereArgs)
表名字 键值对(可添加多个) 当什么时候引起 什么时候
cv.put("content", ettext);

【删除表中的数据】
public void delete(String id){
//打开数据库
db=dbHelper.getWritableDatabase();
//删除数据
db.delete("note", "_id=?", new String[]{id} );

//String sql="delete from note where _id=?";
//db.execSQL(sql, new Object[]{id});
//关闭数据库
db.close();

}

3.在Android中使用SQLite常用API
1)SQLiteDatabase (数据库对象)
|--->此对象如何获得?
2)SQLiteOpenHelper (工具类)
|--->此类如何应用?
-----------------------------------------------

【数据库可视化】
SQLiteSpy.exe

 

new Android layout


【UI简介】
Day13-Android UI简介
----------------------------------------------
1.何为UI?

User Interface (用户接口)

对于接口这个概念,在it行业有两个层面的意思?

1)用户与系统之间的接口(User Interface)
2)系统与系统之间的接口(interface IA{})

在Android中负责与用户进行交互的UI,通常可以理解为View.

何为View 呢?

Android 中所有看的到一切组件对象都是
view.

2.Android 中的UI?

Android中的UI主要是借助View及View的子类实现。

View 的分类:
1)基础View(TextView,EditText,Button,ImageView,....)
2)容器View(继承ViewGroup)
|-->LinearLayout,RelativeLayout
|-->GridLayout,FrameLayout,TableLayout
|-->ListView,GridView,Spinner,.......

3.Android中ListView(列表视图)组件的应用?
1) ListView 是什么?
a) 是一个ViewGroup(特殊的view)?
b) 是一个列表组件(以列表的形式显示数据)?

2)ListView 的应用场合?
a)天猫商品列表
b)微信好友列表
c)新闻列表

3)ListView 构成分析?

a) ListView 容器
b) Item 列表项目(item布局+数据)
c) Adapter(适配器)

4)ListView 是实现原理?

ListView在显示数据时主要是借助Adpater将数据源中的数据以及item布局构建成Item
对象,然后将item对象放到ListView中显示。

5)ListView应用的实现?
a)基本步骤
b)添加监听器
c)设置选择模式(3种)
d)删除ListView中的选项?


Day14-1 内容回顾
----------------------------------------------
1.ListView 是什么?
2.ListView 的应用场合?
3.ListView 的构成分析?(基本构成要素)
4.ListView 的实现原理分析?
5.ListView 应用的构建?
1)基本构建过程
2)事件处理
3)选择模式设置
4)删除ListView内容
5)ListView的更新(调用adapter的notify....)
6)扩展(选项菜单 Menu)
7).............................
6.常用Adapter分析
1)ArrayAdapter (数组或List<T>)
2)SimpleAdapter (数据源List<Map<String,Object>>)
3)SimpleCursorAdapter (数据源 Cursor)
4)BaseAdapter(基类,抽象类)
当官方提供的adapter不能满足我们的数据
要求是我们可以自己定义adapter,
-----------------------------------------------


1)数据库(SQLite)
2)Cursor
3)ListView (SimpleCursorAdapter)

--------------------------------------------
作业
1.总结
2.实现一个自定义Adapter,显示List<Contacts>
集合中的数据?(Day14_listview_6(BaseAdapter))
3.航空列表页面排序操作实现?
-------------------------------------------


【ListView优化】
Day15-1 ListView优化
-----------------------------------------------
1.重用适配器getView方法中的ConvertView参数对象

covertView对象是被移出的item对象(列表项目)。

if(convertView==null){
convertView=构建view item;
}

2.减少适配器getView方法中findViewById的执行
次数?

添加ViewHolder对象,借助此对象保存convertView
对象中子元素对象的地址。

3.按需加载数据(分页加载)
1)每页只加载一页数据(工作线程)
|-->何时去加载?
2)每次加载都需更新ListView

4.缓存数据(尤其是图片);

1)第一次读取网络中图片
2)将图片缓存到本地SDCARD(写)
3)下一次读取图片先读sdcard
-----------------------------------------

 

 

 

--------------------------------------------
【分块显示】
Day16-2 Listview 分块显示

1.场合?
1)数据量比较小
2)数据一次加载完成

2.实现?

1) 让adapter实现接口SectionIndexer
2) 重写相关方法
a)getPositionForSection(int sec)
b)getSectionForPosition(int pos)
c)getSections

案例:

position key section
0 A 65
1 A 65
2 B 66
3 C 67
4 C 67
getPositionForSection(66)=2
getPositionForSection(67)=3
getSectionForPosition(0)=65
getSectionForPosition(1)=65

----------------------------------------------
Day16-2 Listview 右边导航显示

1.思路?

1)在右侧再添加一个ListView
2)在ListView中添加监听器,当
点击某个key时定位到联系人列表的某个位置。

2.实现?

1) key是有序的吗?是
2) key允许重复吗?不允许

Key的获得方式?
1) 个数不固定(key由联系人的名字获得)
2) 个数固定(将26个字母全部放置在listview中)
-----------------------------------------------
Day16-3 ListActivity 的应用

在此Activity中默认提供了一个ListView,在编写Activity时可以继承ListActivity,
直接使用其中的ListView,可以简化简单listview应用的编写。

class MainActivity extends ListActivity{

}
---------------------------------------------
Day16-4 ExpandableListView 的应用(作业)

ExpandableListView 是一个特殊ListView可以对ListView中的内容实现分组显示,
显示效果类似手风琴。其实现原理类似ListView.

具体实现:
仿照官方API demos中view包下的
ExpandableList1.java
ExpandableList2.java
ExpandableList3.java
-------------------------------------------
作业
1.自己实现ExpandableListView 的实现
2.自己实现一个AutoCompleteTextView?
3.自己实现一个Spinner?(下拉列表)
4.自己实现一个GridView(网格视图)

学会看:APIDemos
--------------------------------------------


Day18-1 内容回顾(类似ListView组件的应用)
-----------------------------------------------
1.ExpandableListView (扩展ListView)
2.AutocompleteTextView(自动完成)
3.Spinner (下拉列表)
4.GridView(网格视图)

扩展:图片压缩显示,Bitmap位图对象
-----------------------------------------------
Day18-2 滚动视图的应用

1.垂直滚动(ScrollView)
2.水平滚动(HorizontalScrollView)

【bitmap】
//把bitmap转成byte[],返回一个地图的String模式,发送地图的String,
btnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
if (mapView.getVisibility() == View.VISIBLE) {// 发地图
baiduMap.snapshot(new SnapshotReadyCallback() {
@Override
public void onSnapshotReady(Bitmap bitmap) {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 30,
byteArrayOutputStream);
body = ChatUtil
.addImageTag(byteArrayOutputStream
.toByteArray());
sendMessage(body);
mapView.setVisibility(View.GONE);
} catch (Exception e) {
// TODO: handle exception
}
}
});
} else {// 发文本
body = etBody.getText().toString();
etBody.getText().clear();
sendMessage(body);
}
} catch (Exception e) {
ExceptionUtil.handleException(e);
}
}
});

Day18-1 内容回顾(类似ListView组件的应用)
-----------------------------------------------
1.ExpandableListView (扩展ListView)
2.AutocompleteTextView(自动完成)
3.Spinner (下拉列表)
4.GridView(网格视图)

扩展:图片压缩显示,Bitmap位图对象
-----------------------------------------------
Day18-2 滚动视图的应用

1.垂直滚动(ScrollView)

2.水平滚动(HorizontalScrollView)

-----------------------------------------------
Day19-3 选择框视图对象

1.CheckBox (复选框)
2.RadioButton(单选框):通常放到RadioGroup中

1)实现单选
2)实现底部菜单

扩展:状态选择器(selector)-->
对应drawable目录中的

<RadioButton
android:textColor="@drawable/selector...."
android:drawableRight="@drawable/selector...">

selector中的item可以是自己绘制的图形(shape),
图形可以对应一个

Selector

View--->Sector.-----------------------------------------------

 


Day19-1 内容回顾
----------------------------------------
1.滚动视图
1)垂直(ScrollView)
2)水平 (HorizontalScrollView)
2.选择视图
1)单选 (RadioButton,RadioGroup)
2)复选 (CheckBox)
3.选择器(1)Selector (设定item状态)
2)Shape (绘图)
选择器可以使view对象在不同状态显示不同
效果。

记住:对于一个view而言我们在学习时主要
从如下几个方面着手:
1)此View 是什么?
2)表现形式是怎样的?
3)应用场合?
4)此View对象如何构建?(属性,方法)
5)此View对象上的常用监听器?
---------------------------------------------
Day19-2 菜单的应用?


【菜单】
1.选项菜单(Option Menu)

1)重写onCreateOptionsMenu创建选项菜单
2)重写onOptionsItemSelected处理菜单项
点击事件

2.子菜单(SubMenu)
Java实现:调用Menu.addSubMenu方法。

3.上下文菜单(Context Menu)
此类型菜单的实现需要在view对象上进行注册
,一般是长按某个view时,弹出菜单。

1)重写此方法onCreateContextMenu
2)注册上下文菜单:registerForContextMenu(view)
3)重写activity中的onContextItemSelected
方法,处理上下文菜单项的点击事件

4.弹出式菜单(PopuMenu):

参考APIDemos

所有的菜单都是Menu,在Menu中可以放
item(菜单项),此菜单项对象的构建有两
种方式,一种是由底层框架解析 过反射构建,一种形式是我们自己通过Java
代码构建。
--------------------------------------------


Day20-2 对话框的应用

【对话框】
1.AlertDialog(提示对话框)
2.ProgressDialog(进度对话框)
|-->ProgressBar
SeekBar,
RatingBar
3.DatePickerDialog(日期对话框)
4.TimePickerDialog(时间对话框)

------------------------------------------------
Day20-3 自定义view
【自定义view】

当官方给的view不能完全满足我们需求时,
我们可以自己定义一些view,我们自己定义
的view都会直接或间接的继承View类,需
要重写view中的onDraw方法?

Android中UI实现?
1.Android view组件
2.HTML5

自定义View:
class MyView extends View{}
class MyView extends EditText{}
class MyView extends LinearLayout{}

-----------------------------------------------
【在onClick时不匹配时报错,边框变色】
textview.setBackgroundResource(R.drawable.ic_l); //自己新建selector和shape

 

 

 


Day21-1内容回顾
----------------------------------------------
1.对话框(Dialog)

1)AlertDialog //对话框例子 http://www.cnblogs.com/Gaojiecai/archive/2011/12/10/2283156.html
2)ProgressDialog
a)ProgressBar
b)SeekBar
c)RatingBar
3)DatePickerDialog
a)DatePicker
b)TextClock
4)TimePickerDialog
b)TimePicker

2.自定义的View

自定义view直接或间接的继承view
,重写onDraw方法。

class CircleView extends View{}

class MyEditText extends EditText{}

----------------------------------------------
Day21-2 ViewPager 组件的应用
【ViewPager】
ViewPager的实现原理类似ListView.

可以将ViewPager理解为一个容器(Container)
,此容器中可以存储多个item,每个item对象
的构建需要借助Adapter对象(PagerAdapter)。

ViewPager定义在
android.support.v4.view 包中。

 

 


【删除view】
layout.removeView(viewPager);

 

【让banner条自动滚动】
private boolean isScroller=true;
public void setBannerScroller(){
final Handler h=new Handler();
h.postDelayed(new Runnable() {
@Override
public void run() {
if(viewPager.getCurrentItem()==imgs.length){
viewPager.setCurrentItem(0);
if(!isScroller)return;
h.postDelayed(this, 3000);
}else{
viewPager.setCurrentItem(viewPager.getCurrentItem()+1);
if(!isScroller)return;
if(viewPager.getCurrentItem()==imgs.length){
h.postDelayed(this, 1);
}else {
h.postDelayed(this, 3000);
}
}
}
}, 5000);
}

 


Day22-1 Activity
---------------------------------------------
1.Activity 是什么?

1)Android 四大核心组件之一,作为组件的表现是它的生命周期方法(例如onCreate,onDestory)

2)Android 中的控制器(Controller)
例如记事本:

View
----------------------
Activity (setContentView)
|-->接收view中的数据
|-->对view中的数据进行验证
|-->将数据交给业务model(DBcontext)
----------------------
DBContext(借助此类访问数据库)
----------------------
DB(数据库)

以上模型为MVC架构模式的一种体现
V:View (负责显示逻辑)
C:Controller (负责控制逻辑)
M:Model (负责业务逻辑的处理)

3)Android中的Context(上下文对象),作为Context的一种表现是具备强大的资源访问
能力。(例如SDCARD,项目中资源)

context.getResources().....

4)不是Android中的view.

Activity中包含一个window对象(PhoneWindow),在此窗口中可放一些其它的view对象。

2.Acitivity 类的编写及对象的创建

1)编写
class BaseActivity extends Activity{}
class MainActivity extends BaseActivity{}

2)注册

我们每个Activity都需要在AndroidManifest.

<activity android:name="包名.类名"/>

3).对象的构建

Activity对象的构建由底层框架(AF)构建?
1)解析AndroidManifest.2)通过反射构建Activity的对象。
Class.forName("包名.类名").newInstance()
说明:在我们写的activity中要提供一个无参的构造函数。

Android 官方:Google(提供AF,标准)
Android 厂商:企业(提供APP,标准的实现)

3.Activity对象的生命周期?

Activity对象的生命周期指的是对象从创建,初始化,服务,销毁这个过程所经历的几个阶段。

Activity对象从创建到销毁每个状态都有其对应的生命周期方法,在生命周期
方法中我们可以根据业务的不同,执行不同的业务处理。

1)onCreate()
2)onStart()
3)onRestart()
4)onResume()
5)onPause()
6)onStop()
7)onDestory()

onFinishInflate() 当View中所有的子控件均被映射成onMeasure(int, int) 确定所有子元素的大小
onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发
onSizeChanged(int, int, int, int) 当view的大小发生变化时触发
onDraw(Canvas) view渲染内容的细节
onKeyDown(int, KeyEvent) 有按键按下后触发
onKeyUp(int, KeyEvent) 有按键按下后弹起时触发
onTrackballEvent(MotionEvent) 轨迹球事件
onTouchEvent(MotionEvent) 触屏事件
onFocusChanged(boolean, int, Rect) 当View获取或失去焦点时触发
onWindowFocusChanged(boolean) 当窗口包含的view获取或失去焦点时触发
onAttachedToWindow() 当view被附着到一个窗口时触发
onDetachedFromWindow() 当view离开附着的窗口时触发,Android123提示该方法和 onAttachedToWindow() 是相反的。
onWindowVisibilityChanged(int) 当窗口中内容的可视性在 GONE 、 INVISIBLE 和 VISIBLE 之间变更时调用

【onTouchEvent】
//onTouchListener的onTouch方法优先级比onTouchEvent高,会先触发。
//假如onTouch方法返回false会接着触发onTouchEvent,反之onTouchEvent方法不会被调用。
//内置诸如click事件的实现等等都基于onTouchEvent,假如onTouch返回true,这些事件将不会被触发。

onTouchEvent中要处理的最常用的3个事件就是:ACTION_DOWN、ACTION_MOVE、ACTION_UP。
这三个事件标识出了最基本的用户触摸屏幕的操作,含义也很清楚。虽然大家天天都在用它们,但是有一点请留意,ACTION_DOWN事件作为起始事件,它的重要性是要超过ACTION_MOVE和ACTION_UP的,如果发生了ACTION_MOVE或者ACTION_UP,那么一定曾经发生了ACTION_DOWN。
从Android的源代码中能看到基于这种不同重要性的理解而实现的一些交互机制,SDK中也有明确的提及,例如在ViewGroup的onInterceptTouchEvent方法中,如果在ACTION_DOWN事件中返回了true,那么后续的事件将直接发给onTouchEvent,而不是继续发给onInterceptTouchEvent。

一次完整的事件流程处理: //Intercept 拦截 //dispatch 分派
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev)这个方法用来拦截TouchEvent
...只有ViewGroup才有onInterceptTouchEvent()方法,因为最小单位的View不具备再往下派发事件的能力,它只会直接调用自己的onTouch()和onTouchEvent()方法。
3)public boolean onTouchEvent(MotionEvent ev)这个方法用来处理TouchEvent
当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View,
TouchEvent最先到达最顶层 view的 dispatchTouchEvent,然后由 dispatchTouchEvent方法进行分发,
如果dispatchTouchEvent返回true,则交给这个view的onTouchEvent处理,
如果 dispatchTouchEvent返回 false,则交给这个 view的 interceptTouchEvent方法来决定是否要拦截这个事件,
如果 interceptTouchEvent返回 true,也就是拦截掉了,则交给它的onTouchEvent来处理,
如果 interceptTouchEvent返回 false,那么就传递给子 view,由子 view 的dispatchTouchEvent再来开始这个事件的分发。
如果事件传递到某一层的子 view的 onTouchEvent上了,这个方法返回了 false,那么这个事件会从这个 view往上传递,都是onTouchEvent来接收。
如果事件传递到某一层的子view的onTouchEvent上了,这个方法返回true,那么这个事件将不会向上传递了,又这个view拦截处理.
而如果传递到最上面的 onTouchEvent也返回 false的话,这个事件就会“消失”,而且接收不到下一次事件
在没有重写onInterceptTouchEvent()和onTouchEvent()的情况下(他们的返回值都是false), 对上面这个布局,MotionEvent事件的传递顺序如下:
当某个控件的onInterceptTouchEvent()返回值为true时,就会发生截断,事件被传到当前控件的onTouchEvent()。
如我们将LayoutView2的onInterceptTouchEvent()返回值为true,则传递流程变成:
如果我们同时将LayoutView2的onInterceptTouchEvent()和onTouchEvent()设置成true,那么LayoutView2将消费被传递的事件,
同时后续事件(如跟着ACTION_DOWN的ACTION_MOVE或者ACTION_UP)会直接传给LayoutView2的onTouchEvent(),不传给其他
任何控件的任何函数。同时传递给子空间一个ACTION_CANCEL事件。传递流程变成(图中没有画出ACTION_CANCEL事件):


【启动模式】
4.Activity 对象的启动模式(四种)

其中模式的配置一般在AndroidManifest.中的activity标签中进行配置。

android:launchMode="模式"

1)standard (每次都会创建一个新的activity)//这种启动模式,退出时直接退出,不会黑屏

启动:
ActivityA--->ActivityB--->ActivityA
任务栈:
ActivityA
ActivityB
ActivityA

2)singleTop(当activity处于栈顶时不再创建Activity)

启动:
ActivityA--->ActivityB-->ActivityB
任务栈:
ActivityB
ActivityA

3)singleTask(一个任务栈只能有一个Activity)
启动:
ActivityA--->ActivityB-->ActivityC-->ActivityA
任务栈
ActivityC 销毁
ActivityB 销毁
ActivityA 启动
一般会将首页设置为SingleTask模式
还有一般的浏览器也会设置为此模式

4)singleInstance(此activity独占一个任务栈) //这种启动模式,退出时会黑屏

启动:
ActivityA--->ActivityB(singleInstance)

任务栈A: ActivityA
任务栈B: ActivityB (独立的占有一个任务栈)

例如:拨号程序应该是一个SingleInstance

5.Activity 状态信息保存

保存的位置:内存,外存
保存的时机:Activity正在离开可视范围。
保存的方法:onSaveInstance
|-->保存到bundle对象中
|-->保存到文件(SharedPreferences)或者sqlite数据库
恢复的方法:onCreate或者onRestoreInstanceState

6.Activity 之间数据的传递?

一般要借助intent对象。

Intent intent=new Intent(this,XXXActivity.class);
intent.putExtra(.....)
startActivity(intent);
//=====
假设需要从被启动的Activity回传数据

startActivityForResult(.....) //setResult在什么时候调用?

在startActivityForResult搜索启动一个activity的时候调用。
比如A activity以startActivityForResult方式启动一个B activity。当B activity setResult的时候,A activity 的onActivityResult()
回调函数就会响应该事件。不知是否明白,不明白再继续追问。也可以百度一下startActivityForResult用法
在本Activity重写onActivityResult接收回传的数据

 

----------------------------------------------
Day22-2 Fragment (碎片,片段)

【Fragment】
1.Fragment是什么?(Android3.0)

Fragment是Activity中模块化组件,其生命周期
依托于Activity.一般用于动态的更新Activity中的
内容.

2.Frament类的编写及应用?

1)所有的Fragment都直接或间接的继承Fragment
2)编写好的Fragment无需到清单配置文件注册,
但需要添加到Activity中显示。

3.预习Fragment对象
-----------------------------------------------

 

Day23-1 项目概要
---------------------------------------------
1.功能需求?
1) 欢迎页面
2) 新手指导
3) 系统主页
4) 航班查询
5) 航班列表
6) 航班动态
7) 个人信息
8) ......

2.系统架构

1)整体架构:C/S架构 (服务端数据聚合数据)
2)局部架构:MVC

3.代码约束

包的定义: //包的命名规则

1)所有的activity存储在:
com.company.gars.activity 包中
2)所有的业务相关定义在
com.company.gars.model包中
3)所有的自定义view定义在
com.company.gars.view包中
4).所有的工具类都定义在
com.company.gars.util包中

类名的定义:

1)Activity: XXXActivity
2)View: XXXView
3)Model: XXXService
4)util:XXXUtil
5)Adapter:XXXAdapter
.....

变量名,常量名,方法名等都要遵循标识符的定义

项目名称:GSD1503GARS01

4.代码实现
-----------------------------------------------
Day23-2 欢迎页面

1.功能需求?

1)系统启动第一个页面,启动模式为标准模式,
默认停留5秒。
2)此页面全屏显示,且竖屏显示。
3)5秒以后,根据系统使用状态进入下
一个页面。不能返回。
4)显示系统版本信息。(参考GARSV02)
5)页面上添加一个滚动条(无进度显示),
表示页面正在加载。也可选择添加
动画。
6)图片显示时,是经过压缩处理的,
压缩比例应该适配屏幕尺寸。
图片应该来自网络(先不实现)
7)图片上添加点击事件。
8)检测版本更新(联网状态)

2.代码实现????????


----------------------------------------------
Day23-3 新手指导页面

1.功能需求
1) 第一次使用系统,进入此页面,屏蔽回退操作。
2) 此页面竖屏,全屏显示,启动模式为标准模式
3) 页面可以分页显示,页面上要有页面指示器
4) 最后一页要有按钮,点击按钮进入主页
5) 进入主页以后不能返回(关闭当前页面)
6) ........

2.代码实现?

技术要求:ViewPager+fragment


【so文件】【jar包】【预设】
预置的app系统不会给你安装so文件,如果你的app需要用到so文件,需要自己打包到/system/lib/目录;
非预置的app系统会提取到你应用的私有目录的lib目录下。
至于jar文件,并不存在安装到哪里这一说法,要么是已经打包在apk里面,要么在/system/framework目录
/system/framework目录的都是系统预置的,你不用管
你eclipse导入jar包时(Build Path-&gt;Configure Build Path...-&gt;Order And Export)那一页,
要是打勾就包含在apk里,否则不包含
编译好的Apk内有so文件,但是没有jar包。jar包应该是已经编译进代码中了

提问::::当初我做一个项目,海尔电视,使用了对方提供的jar包之后,这儿(Order And Export)也没有勾选,但是也可以调用对方的方法,为什么?
我自己的答案:应该是因为海尔电视本地/system/framework就有这个jar包,所以即使我们的app内没有这个jar包也可以调用海尔电视的方法。

提问::::系统预设了movie之后,我再手动安装了一个movie更新,系统会从apk内提取了so文件,但是这个so文件还是以前的,
为什么还是可以解析电影(只有system/lib目录中最新的的so文件才可以解析),难道system/lib中的so文件的优先度比较高?
答:只有在系统预设了movie之后,才会优先使用system/lib目录的so文件,
在系统没有预设movie的情况下,系统会优先使用data目录中的so文件

 

【设置版本信息】 //设置APP版本信息
private void setVersionCode(){
//获得PackageManager,
//可以借助此对象读取配置文件(AndroidManifest. //中的版本信息。
PackageManager pm=getPackageManager();
try{
PackageInfo pi=
pm.getPackageInfo(getPackageName(),0); //填0就可以了
TextView tv=
(TextView)findViewById(R.id.versionText);
tv.setTextColor(Color.RED);
tv.setText("版本:"+pi.versionName);
Log.i("TAG", "pi.versionName="+pi.versionName);
}catch(Exception e){
e.printStackTrace();
}
}

【设置返回按钮】
<activity
android:name="com.company.gars.activity.BookTicketActivity"
android:label="@string/title_activity_book_ticket"
android:parentActivityName="com.company.gars.activity.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.company.gars.activity.MainActivity" />
</activity>

 

 


【ViewPager】
用了ViewPager,就要用support.v4,没用就可以用app.

【跳转到百度】
// Intent intent = new Intent();
// intent.setAction("android.intent.action.VIEW");
// Uri uri = Uri.parse("http://www.baidu.com");
// intent.setData(uri);
// startActivity(intent);


------------------------------------
【第三位老师】
徐铭
xuming@tarena.com.cn
15201603213


【TOMCAT】
【tomcat】
导入mysql的链接驱动时,直接放在lib里,不用新建libs,也不用进行build path

tomcat的目录结构
bin: 存放tomcat运行时需要的可执行程序。
startup.sh
startup.bat
shutdown.sh
shutdown.bat

conf: tomcat运行时所需要的一些配置文件。
注意: server.

lib: tomcat运行时所需要的jar包。

logs: tomcat运行时输出的日志信息。

webapps:
tomcat的应用程序部署目录。所有的web
服务应用都在这个文件夹下(默认)


通过网络如何访问tomcat管理的web服务端应用?
1> 在本地启动tomcat服务
192.168.188.40:8080
配置JAVA_HOME环境变量
避免8080端口没有被占用

2> 打开浏览器,输入请求地址,格式如下:
http://192.168.188.40:8080/应用名称/访问路径

http://192.168.188.40:8080/docs/index.html
http://localhost:8080/docs/index.html


鸬絫omcat/webapps中。
3> 启动tomcat,打开浏览器访问相应地址。

http://localhost:8080/downloads/lml.zip


如何编写一个动态的服务端程序?(带有业务逻辑)


服务端JSP文件的执行流程:
1>浏览器发送Http请求,访问一张jsp页面:
http://localhost:8080/day01/index.jsp
2>tomcat接收该请求,寻找是否含有相同名称的jsp如果没有,则404.
3>如果找到该jsp文件,tomcat会寻找该jsp文件生成的.java文件,并且自动运行该类中的_jspService方法。
4>service方法里,tomcat将会把我们写在jsp里的文本内容使用out.write方法输出。
5>tomcat将会把这些需要输出的内容封装http响应数据包返回给客户端。
6>浏览器接收该响应数据包后,解析响应数据并且呈现页面。


JSP的组成部分:
1>JSP指令
<%@page language="java"
contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
contentType:
向客户端指明jsp返回的数据格式与编码。
pageEncoding:
tomcat生成.java文件时所使用的编码。

2>Java代码片段
JSP的本质就是一个Java类,所以我们可以在jsp文件中编写java代码。
<%%>
在<%%>中的代码,tomcat将会原封不动的输出到
.java类文件中,这样我们可以在jsp文件中输出一些
动态的数据,非常方便。

3>普通的文本
tomcat将会通过out.write方法把这些字符串输出给客户端。

4>JSP表达式 (用于输出java变量)
<%=%>
tomcat将会在相应的位置输出这些变量的值。


模拟返回<flights>
<flight id="">
<name></name>
<startDate></startDate>
</flight>
</flights>

【导出】
把eclipse中的web服务端应用打包。
右键项目--->export --> 搜索war--->选择目标目录 --> ok

把war包部署到tomcat的wabapps文件夹中,然后重新启动tomcat,重新访问。


【mysql中】
【为了让名字可以显示的不是乱码】
set names gbk;

【web文件】
老师给的web文件,我们的电脑配置不一样,所以无法使用,要把老师的web文件中的WebContent和src文件复制到我们新建的同名web文件中,再自己导出,才不会出现配置错误的现象。

【第一次建Web】
选择Apache Tomcat v6.0

day02
----------------------------------------------------
【HTTP协议详解】 //httpget
【GET】、【POST】请求类型
如何使用HttpClient相关API让Android发送请求
JSON


HTTP协议详解:
HTTP协议定义了客户端与服务端之间的通讯过程
及数据包的格式。

Http协议的通讯过程:
HTTP协议是一款基于短连接的协议。 //网页
短连接的特点:
节省服务器资源。但是没有办法实时同步数据。
长连接的特点:
可以维护数据的实时性。

socket(长连接) //游戏

HTTP协议数据包的结构:
HTTP请求数据包:
1>请求行
GET /day01/index.jsp HTTP/1.1
GET: 请求方式
/day01/index.jsp: 请求资源路径
HTTP/1.1: 协议的类型与版本

2>请求消息头
Content-Type: text/html
key: value
key: value
这些key: value键值对用于描述客户端发送请求数据包
中数据的一些状态及客户端的一些状态信息。

3>请求实体
主要在POST请求方式时存放请求参数


HTTP响应数据包:
1>状态行
HTTP/1.1 200 ok
协议的类型与版本
响应状态码
响应状态码的描述

2>响应消息头
key: value
用于描述服务端的状态及服务端返回数据的状态信息。

3>响应实体
用于存放返回给客户端的数据

GET、POST请求类型
HTTP请求的类型有很多种:PUT DELETE .....

GET/POST的区别:
1>请求参数的存放位置
GET: 参数存放在请求资源路径后面用?拼接。
http://ip:port/day01/x.jsp?name=zs&pwd=1234
String name=request.getParameter("name");
String pwd=request.getParameter("pwd");
POST: 参数存放在请求数据包的实体部分。

2>安全性
GET:相对不安全
POST:相对安全
3>是否适合传递中文参数
GET:不适合
POST:适合
4>是否适合大数据量提交
GET:不适合
POST:适合

 

如何使用HttpClient相关API让Android发送请求
如何发送get请求
如何发送post请求
如何解析HTTP响应

如何发送get请求
HttpClient client=new DefaultHttpClient();
String uri="http://localhost:8080/day01/loadEmps.jsp";
HttpGet get=new HttpGet(uri);
HttpResponse resp=client.execute(get);
HttpEntity entity=resp.getEntity();
String json=EntityUtils.toString(entity);

JSONObject obj=new JSONObject(json);
String result=obj.getString("result");
if("ok".equals(result)){
JSONArray ary=obj.getJSONArray("data");
List<Music> musics=parseJSON(ary);
return musics;
}

部署服务端项目ems:
部署成功后访问:
http://localhost:8080/ems/addEmp.html
看到添加员工页面,输入信息后添加成功。


开发客户端程序:
查询员工列表
添加员工信息
注册业务
登录业务


查询员工列表
当MainActivity打开时,看到ListView里面显示所有的
员工数据。


什么是JSON?
json是一款轻量级的数据交换语言。

json的常见格式:
json对象:
{ "id": 1,
"name":"zs",
"aihao":[ "吃","吃","吃" ],
"married":true,
"dept": { "name":"cwb", "loc":"bj" }
}

json数组:
[ "吃",100, true, { } ]


解析json:
{"result":"ok",
"data": [
{"id":1,
"name":"zhangsan",
"salary":12345.0,
"age":12,
"gender":"m"},
{"id":2,
"name":"zhangsan",
"salary":12345.0,
"age":12,
"gender":"m"}
]
}


如何解析json对象及json数组:
str={ "id": 1,
"name":"zs",
"aihao":[ "吃","吃","吃" ],
"married":true,
"dept": { "name":"cwb", "loc":"bj" }
}

JSONObject obj=new JSONObject(str);
obj.getInt("id");
obj.getString("name");
obj.getJSONObject("dept").getString("loc");
obj.getJSONArray("aihao");


str=[ "吃", "吃", "吃", "吃"]
JSONArray ary=new JSONArray(str);
for(int i=0; i<ary.length(); i++){
String ele=ary.getString(i);
}
ary.getInt(index)
ary.getJSONObject(index)
ary.getJSONArray(index)
ary.getXXX(index)


如何发送POST类型的请求?
HttpClient client=new DefaultHttpClient();
String uri="http://xxxxxxxxx/addEmp";
HttpPost post=new HttpPost(uri);
//如果要传递参数
List<NameValuePair> list=new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("name", "zs"));
list.add(new BasicNameValuePair("name", "zs"));
HttpEntity entity=new UrlEncodedFormEntity(list, "utf-8");
post.setEntity(entity);
//设置post对象的Content-Type消息头:
post.setHeader("Content-Type","application/x-www-form-urlencoded");
//发送请求
HttpResponse resp=client.execute(post);


完善添加员工业务:

 

 

day03
----------------------------------------------------
HTTPClient相关API:
HttpClient
DefaultHttpClient
HttpUriRequest
HttpGet
HttpPost
setHeader()
setEntity()
client.execute(HttpUriRequest)
HttpEntity
UrlEncodedFormEntity( list, "utf-8" )
NameValuePair
BasicNameValuePair
name=zs&pwd=1234&age=20

HttpResponse
getStatusLine()
getAllHeaders()
getEntity()
StatusLine 用于描述状态行
getProtocalVersion();
getStatusCode() 获取状态码
Header 用于描述消息头

EntityUtils
toString()
toByteArray()

-----------------------------------------------------
HTTP协议的状态管理
HTTP协议是一款基于短连接的协议。所以基于HTTP协议
的请求是无状态的。

什么是HTTP的状态管理?
HTTP状态管理应该由服务端与客户端协同管理,才
可以实现把同一个客户端发送的多次请求当成一个
整体来看待,把同一个客户端的多次请求中涉及
到的数据保存下来。

实现状态管理的方式:
Cookie机制
Session机制

Cookie机制的实现原理:
当发送第一个请求时,服务端将会在返回的响应数据包
中设置Set-Cookie消息头。
Set-Cookie: key=value
当发送后续请求时,客户端需要在请求数据包中添加
如下消息头:
Cookie: key=value


Session机制 (把数据存入了服务端)
仅仅了解原理。

 

音乐播放器的列表展现:
http://192.168.188.68:8080/musicsonline/loadMusics.jsp


【设计客户端架构:】
com.tarena.musicclient
activity 存放activity
MainActivity
entity 存放实体类
Music
util 存放工具类
HttpUtils 用于发送http请求的工具类
adapter 存放适配器
MusicAdapter
biz 存放业务类 AsyncTask
MusicBiz extends AsyncTask
List<Music>


使用单线程轮询任务队列的机制异步批量加载图片


day04
------------------------------------------------
【图片的压缩:】

public static Bitmap loadBitmap(byte[] bytes, int width, int height){
Options opt=new Options();
//是否仅仅加载图片的边界属性
opt.inJustDecodeBounds=true;
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
//获取图片的原始宽度和高度
int w=opt.outWidth/width;
int h=opt.outHeight/height;
int scale=w>h ? w : h;
//设置图片的压缩比例
opt.inSampleSize=scale;
opt.inJustDecodeBounds=false;
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
}

 

Android中的内存泄露:
堆内存中含有一些对象,这些对象在创建后忘了销毁(C),或GC无法销毁(Java),那么这些对象就是内存中的
垃圾对象,占用着内存,我们称这种现象为内存泄露。

为何在Java 的 GC环境下还会出现内存泄露?
场景1:
new Thread(){
run(){ ... }
}.start();
如果run方法没有执行完毕,那么该thread对象就会永远持有外部类对象的引用,导致外部类对象没有
办法被GC回收。导致后续对象都没有办法回收。这些对象在java内存中就会成为垃圾对象。


Android中的图片缓存:

HashMap<String, Bitmap> maps=new HashMap<String, Bitmap>();
maps.put("images/a.jpg", bitmap);
maps.put("images/b.jpg", bitmap);
maps.put("images/c.jpg", bitmap);
Bitmap bitmap=maps.get("images/b.jpg");
这种方法会出现OOM 内存溢出


Java中的引用:
强引用:strong References
软引用:soft References

SoftReference sof=new SoftReference(bitmap);

弱引用:weak References
虚引用:

【软引用】
使用软引用实现图片缓存: //存在变量HashMap中,而不是sd卡中
HashMap<String, SoftReference<Bitmap>> cache =new HashMap();
存入缓存:
cache.put("path", new SoftReference(bitmap));
cache.put("path", new SoftReference(bitmap));
cache.put("path", new SoftReference(bitmap));
从缓存中读取:
SoftReference sof=cache.get(path);
Bitmap bitmap=sof.get();


【Exception】
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification.
Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.
[in ListView(2131230721, class android.widget.ListView) with Adapter(class android.widget.HeaderViewListAdapter)]
改成这样了,不保证有效
new Thread() {
public void run() {
//加载10个item
first.addAll(getContacts(pager));
runOnUiThread(new Runnable() {
@Override
public void run() {
if (currentPager == totalPagers) {
lv.removeFooterView(progressBar);
lv.addFooterView(tv);
}
// 刷新listview
adapter.notifyDataSetChanged();

}
});

};
}.start();


day05
------------------------------------------------


实现图片文件缓存:

BitmapUtils{
loadBitmap(String path){
从某一个路径中加载出一个Bitmap对象
}
save(File targetFile, Bitmap bitmap){

}
}


音乐文件的下载:

【进程优先级】
Android中的进程:
理论上说启动一个Android App,系统将会为该App
分配一条进程。
Android中会为每一条进程分配相应的进程优先级。
大致有5中进程优先级:

【前台进程优先级】
1.包含有交互状态的activity实例的进程。
2.包含有正在执行生命周期方法的组件的实例的进程。
3.包含有与交互状态activity绑定在一起的service实例
的进程。
4.包含有执行了setForground(true)方法的service实例
的进程。


【可见进程优先级】
1.包含有暂停状态的activity实例的进程。
2.包含有与暂停状态activity绑定在一起的service实例的进程。

【服务进程优先级】
1.包含有正在运行service实例的进程。

【后台进程优先级】
包含有停止状态activity实例的进程。

【空进程】
不包含任何组件的进程。用于当android需要开辟
新进程时,可以直接使用这些空进程,不需要现用
现创建。 优先级最低。

Android四大组件之----
【Service】

什么是Service?
1.service是android中四大组件之一
2.service本质上是后台运行的程序。没有activity那样
的用户界面。
3.service是Context类的子类。
4.service适合用于长时间后台运行的场合。
5.service具有较高的进程优先级---服务进程。
6.service运行时全局单例。

容器与组件:
组件是需要在容器的管理下运行的。
组件的创建由容器管理。
组件的生命周期方法的执行也是由容器管理的。
我们仅仅需要在组件响应的生命周期方法中编写
相关代码即可。容器就会自动调用。

服务的生命周期
服务的生命周期跟启动服务的方法有关:
当采用Context.startService()方法启动服务,与之有关的生命周期方法
onCreate()? onStartCommand() ? onDestroy()
onCreate()该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onStartCommand() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。
多次调用startService()方法尽管不会多次创建服务,但onStartCommand() 方法会被多次调用。
onDestroy()该方法在服务被终止时调用。

当采用Context.bindService()方法启动服务,与之有关的生命周期方法
onCreate()? onBind() ? onUnbind() ? onDestroy()
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,
当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用。
如果先采用startService()方法启动服务,然后调用bindService()方法绑定到服务,再调用unbindService()方法解除绑定,
最后调用bindService()方法再次绑定到服务,触发的生命周期方法如下:
onCreate() onStartCommand()?onBind()?onUnbind()[重载后的方法需返回true]?onRebind()
利用bindservice()调用服务里面的方法:
开启服务 (startservice)
服务一旦开启与调用者没有任何的关系 , 调用着的activity 即便是退出了 不会影响。后台的service的运行.在activity里面 不能去调用服务里面的方法 .

通过绑定方式开启服务(bindservice)
服务跟调用者不求同生 ,但求同死.如果调用者(activity)退出了 那他绑定的服务呢 也会跟着退出.我们可以在activity里面调用服务里面的方法.
利用 serviceSonnection 接口 返回一个ibinder对象 , 拿着ibinder对象获取到服务里面方法的引用(自定义了一个接口信息) ,调用服务里面的方法 。

让activity可以调用service中的方法。
Service中
public class LocalBinder extends Binder {
ServiceLocation getService() {
// Return this instance of LocalService so clients can call public
// methods
return ServiceLocation.this;
}
}
在ACtivity中
private ServiceConnection mConnection = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName className, IBinder service) {
// We've bound to LocalService, cast the IBinder and get
// LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};

【onStartCommand】
* 每次调用startService(不是bindService)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理。
* 返回START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,
* 由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。
* 如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。(non-Javadoc)
* @see android.app.Service#onStartCommand(android.content.Intent, int, int)
*/
public int onStartCommand(Intent intent, int flags, int startId) {
log("onStartCommand(" + intent + "," + flags + "," + startId + ")");
chkAlarm(intent, startId);

return START_STICKY;
};


【存图片时,没用权限,下载音乐时,加了write权限】

 

day06
---------------------------------------------
Android中的通知:Notification
【Notification】
什么是通知?
通知是Android中的一个常用的系统服务。
我们可以使用通知更方便更友好的告知用户一些程序的
运行状态。


在Android中如何发送一个通知:
1.创建NotificationManager对象。
2.创建通知Notification对象,该对象中保存着通知中
的基本信息。
3.调用NotificationManager.notify方法发送通知。

修改通知内容:
再次发送一个相同id的通知即可。(不会有滚动消息)

如何清除通知:
manager.cancel(id);

如何实现通知信息常驻通知栏?
notification.flags=Notification.FLAG_NO_CLEAR;

如何设置通知的点击意图?
Intent intent=new Intent(this, MainActivity.class);
PendingIntent pi=PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pi);

【PendingIntent】
三种不同方式来得到一个PendingIntent实例。
getBroadcast——通过该函数获得的PendingIntent将会扮演一个广播的功能,就像调用 Context.sendBroadcast()函数一样。
当系统通过它要发送一个intent时要采用广播的形式,并且在该intent中会包含相应的 intent接收对象,
当然这个对象我们可以在创建PendingIntent的时候指定,也可以通过ACTION 和CATEGORY等描述让系统自动找到该行为处理对象。
getActivity——通过该函数获得的PendingIntent可以直接启动新的activity, 就像调用 Context.startActivity(Intent)一样.
不过值得注意的是要想这个新的Activity不再是当前进程存在的Activity 时。我们在intent中必须使用Intent.FLAG_ACTIVITY_NEW_TASK.
getService——通过该函数获得的PengdingIntent可以直接启动新的Service,就像调用Context.startService()一样。







实现音乐文件的下载操作:

 

Android中四大组件之 ---- ContentProvider
【ContentProvider】
什么是ContentProvider?
1>ContentProvider是android四大组件之一。
2>ContentProvider提供了android中跨进程数据共享
的规范。
3>ContentProvider是一个抽象类。

数据持久化


什么时候需要编写ContentProvider?
当app需要把私有数据的访问方法开放给外部应用
时。
什么时候需要访问ContentProvider?
当需要访问外部应用程序的私有数据时,需要访问
外部应用程序开放出来的ContentProvider。


如何编写一个ContentProvider?
1>编写一个Java类,必须继承ContentProvider.
2>实现相关的抽象方法。
3>在清单文件中注册。


如何访问ContentProvider?
使用ContentResolver r访问ContentProvider。
ContentResolver r=context.getContentResolver();
r.query()
r.delete()
r.xxxxx


什么是Uri?
统一资源标识符
http://localhost:8080/musiconline/xxx.mp3
file:///xxx/xxx/xxx.jpg?xxx=xxx&xx=xx

http://localhost:80/musiconline/musics/gongtong.mp3?name=zs&pwd=1234#segment
scheme http
host localhost
port 80
authority localhost:80
path musiconline/musics/gongtong.mp3
query name=zs&pwd=1234
segment segment


uri:
content://com.tarena.provider.WORD/

删除:
content://com.tarena.provider.WORD/
content://com.tarena.provider.WORD/words/2
content://com.tarena.provider.WORD/user/2


UriMatcher
matcher=new UriMatcher(UriMatcher.NO_MATCH);
matcher.addUri(....., 1);
matcher.addUri(....., 2);
matcher.addUri(....., 3);
int code=matcher.match(uri);

ContentUris
ContentUris.parseId();
ContentUris.withAppendedId(uri, 30);

 

day07
-------------------------------------------------------
联系人数据库相关操作

系统自带联系人数据库的存放位置

contacts
_id
raw_contact_id
photo_id
data
_id
mimetype_id
raw_contact_id
data1
data15
mimetype
_id
mimetype
raw_contacts
_id
display_name


如何查询所有的联系人数据:
先查询contacts表
获取每个联系人的Id与photo_id
再通过id查询data表
获取每一个联系人的具体数据


ContentResolver r=xx;
uri="content://com.android.providers.contacts/contacts";
r.query(uri, .......);


day08
------------------------------------------------
【Intent】详解
显示意图与隐式意图

Intent对象的6大属性

ComponentName
Bundle
flags
action
category
data

ComponentName 组件名对象
封装了Context与目标组件的类对象。可以描述
Android中的一个具体的组件。如果一个intent对象
中包含完整的ComponentName属性,那么我们
可以说这个intent对象是一个显式意图.
Intent i=new Intent(context, xxx.class);
Intent i=new Intent();
i.setCompnentName(new ComponentName(xxx, xx));


Bundle属性
主要用于组件之间参数的传递。
intent.putExtra();
intent.putExtra("music",new Music());
class Music implements Serializable{ }


隐式意图相关属性:
action 用于描述目标组件可以执行的动作
category 用于描述目标组件所属分类
data 用于描述目标组件处理的数据类型


action 用于描述目标组件可以执行的动作
Android系统中常见的action:
Intent.ACTION_CALL;
Intent.ACTION_DIAL;
Intent.ACTION_VIEW;

我们可以为某一个Activity定义该Activity可以执行的
动作,那么当用户发送隐式意图时将有可能启动我们
写的Activity。

Intent对象对action的测试规则:
1>Intent对象中只能含有1个action
2>intent-filter中可以配置多个action
3>如果intent对象中的action在intent-filter的action
列表范围内,那么action匹配成功。
4>如果intent-filter中没有声明action,拒绝所有的action
的测试。
5>如果intent对象中未包含action,则默认通过
所有的action测试。

startActivity(new Intent("eos.intent.action.ALLACTIVITY")); //值是在androidManifest中加的


category 用于描述目标组件所属分类

Intent对象对category的匹配规则:
1>intent对象中可以包含多个category
2>intent-filter中可以声明多个category
3>如果intent对象中的category是intent-filter中声明
category集合的子集,那么category匹配成功。
4>如果intent对象中不包含任何category,则默认
可以通过所有的category的测试。
5>所有被传入startActivity方法的intent对象都会被
添加一个默认的category:
android.intent.category.DEFAULT

系统中常见的category:
Intent.CATEGORY_APP_BROWSER;
Intent.CATEGORY_APP_CALENDAR;
Intent.CATEGORY_APP_CONTACTS;
Intent.CATEGORY_APP_MAPS;
Intent.CATEGORY_APP_MUSIC;


data 用于描述目标组件可以处理的数据类型。

scheme
host
port
path
mimetype

1>intent对象中包含一个具体的Data(Uri对象)
2>intent-filter中声明当前组件支持的uri的数据格式。
scheme/host/port/path
3>如果intent中的data的格式符合intent-filter声明
的格式的要求,则data匹配成功。
4>如果intent-filter中有data的声明,则intent对象中
必须包含一个具体的Data才可以执行。
5>intent-filter中可以声明data的mimetype,如果
声明可具体的mimetype,则intent对象中必须含有
mimetype属性:
intent.setType("type");
intent.setDataAndType(uri, "type");

Android中的广播机制
Android中的广播接收器

什么是Android中的广播?
广播是Android中实现跨进程数据通信的一种机制。

广播接收器是Android四大组件之一。
【BroadcastReceiver】

我们将会编写广播接收器接收外部发送来的广播,获取
广播内所携带的一些数据,处理相关业务逻辑。


广播的分类:
系统广播
由系统程序发送的广播。常见的有:
Intent.ACTION_BATTERY_LOW;
Intent.ACTION_MEDIA_MOUNTED;
Intent.ACTION_POWER_CONNECTED;
Intent.ACTION_POWER_DISCONNECTED;
Intent.ACTION_SCREEN_OFF;
Intent.ACTION_SCREEN_ON;
Intent.ACTION_BOOT_COMPLETED;


自定义广播
1>普通广播
发送普通广播后,所有的广播接收器接收的动作是
异步的,互相没有关系。
2>有序广播
发送有序广播后,android将会按照广播接收器事先
定义好的优先级,顺序执行每个广播接收器的相关
方法。
3>驻留广播
发送驻留广播后,android将会判断容器中是否含有
可以接收该广播的接收器,如果没有,则该广播不会
立即消失,将会在android容器中驻留,当在这个过程
中注册了一个接收器,那么也会执行接收器相关方法
处理这个广播。


【普通广播】
如何发送一个普通广播?
intent=new Intent("xxxxx");
context.sendBroadcast(intent);

如何编写广播接收器接收普通广播?
1>编写一个Java类,继承BroadcastReceiver
2>重写相关抽象方法。
onReceive(Context context, Intent intent)
3>注册广播接收器。
清单文件注册:
<intent-filter>
<action name=""/>
</intent-filter>
代码注册:
receiver2=new UpdateProgressReceiver();
IntentFilter filter2=new IntentFilter();
filter2.addAction("UPDATE_PROGRESS");
this.registerReceiver(receiver2, filter2);
//context.registerReceiver(receiver, filter);

this.unregisterReceiver(receiver2);
//context.unregisterReceiver(receiver);


案例:
模拟音乐播放器播放过程中的界面展现。

2>【有序广播】
发送有序广播后,android将会按照广播接收器事先
定义好的优先级,顺序执行每个广播接收器的相关
方法。
广播接收器之间可以传递数据。
我们可以终止广播接收器的继续传播。

发送有序广播:
context.sendOrderedBroadcast();
如何接受有序广播:
接受方式与普通广播一致。 但是需要配置优先级。

intentfilter.setPriority(number);
number [-1000~1000]
number越大优先级越高,越先执行。
在广播的过程中可以终止广播的继续传播:
this.abortBroadcast();


3>驻留广播
context.sendStickyBroadcast();
发送驻留广播需要在清单文件中声明权限。

 


day09
--------------------------------------------------------
【媒体提供程序】 ContentProvider

什么是媒体提供程序?
Android操作系统提供了一个媒体数据库用于存储
当前手机内外部存储中所含有的媒体文件相关的基本
信息。并且使用ContentProvider提供给用户。

当系统接收到相关的广播后,将会启动一个系统服务,
该系统服务会扫描内外部存储设备获取媒体文件相关
属性,并且把文件的基本信息更新到媒体数据库中。
Intent.ACTION_BOOT_COMPLETED
Intent.ACTION_MEDIA_MOUNTED

媒体相关数据库:
com.android.providers.media
databases

如何访问媒体提供程序?

查询外部存储中所有的图片文件:
ContentResolver r=context.getxxx();
uri=Images.Media.EXTERNAL_CONTENT_URI;
uri=Audio.Media.EXTERNAL_CONTENT_URI;
uri=Video.Media.EXTERNAL_CONTENT_URI;
Cursor c=r.query(uri, null, xxxxxx);


实现音乐播放器相关业务:
1>点击音乐列表中的某一项可以跳转界面并且播放歌曲。
2>音乐播放的过程中更新Activity的播放进度。
进度条/时间TextView
3>下一曲/上一曲/播放/暂停
4>更新音乐信息时更新Activity的界面显示。 (作业)
5>拖拽进度条实现从当前进度继续播放。 (作业)
6>播放模式。 (作业)
顺序/随机/单曲循环
7>音乐播放完成后继续播放 (作业)
player.setOnSeekCompleteListener(listener)

 

day10
---------------------------------------------------------
AppWidget桌面小部件
什么是AppWidget?

新建的时候是Android

AppWidget是Android中有着良好用户交互体验的一个
组件。要求AppWidget必须继承AppWidgetProvider。

AppWidgetProvider是BroadcastReceiver的一个子类。


如何编写一个AppWidget?
1>设计桌面小部件的布局界面。
2>定义AppWidget的元数据文件。 (meta-data)
AppWidget的初始化布局的 定义AppWidget的宽度
定义AppWidget的高度
3>创建AppWidget控制器类,要求必须继承
AppWidgetProvider. 重写相关生命周期方法。
4>在清单文件中注册该AppWidget。
(broadcastReceiver的注册方式)


计算AppWidget大小的公式:
dp = 70n-30 //android:minWidth="250dp" //4*1
//android:minHeight="40dp"

AppWidget的生命周期:

onEnabled
当第一个AppWidget实例被创建时执行。
onUpdate
每当AppWidget实例被创建时执行。
onDeleted
每当把AppWIdget实例移出时执行。
onDisabled
当把最后一个AppWIdget实例移出时执行。


如何修改AppWIdget界面上的信息?
//1.修改AppWidget中TextView的文字
RemoteViews views=new RemoteViews(
context.getPackageName(),
R.layout.appwidget_main);
//2.对views进行修改
views.setTextColor(R.id.textView1, Color.BLUE);
views.setTextViewText(R.id.textView1, "Hello Android!");
//3.调用updateAppWidget修改界面
manager.updateAppWidget(ids, views);

如何给界面上的控件添加点击意图?
RemoteViews views=new RemoteViews(
context.getPackageName(),
R.layout.appwidget_main);
views.setOnClickPendingIntent();
manager.updateAppWidget(ids, views);


如何点击按钮后修改AppWidget的界面?

//给button2添加点击意图
Intent i2=new Intent("CHANGE_COLOR");
PendingIntent pi2=PendingIntent.getBroadcast(context, 0, i2, PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.button2, pi2);
//当用户点击后将会发送广播
//接收广播


public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
//做自己的工作
String action=intent.getAction();
if(action.equals("CHANGE_COLOR")){
//修改TextView的文字
AppWidgetManager manager =
AppWidgetManager.getInstance(context);
ComponentName provider=
new ComponentName(context,
MyAppWidgetProvider.class);
//创建Views并且更新界面
RemoteViews views=new RemoteViews(context.getPackageName(), R.layout.appwidget_main);
int[] colors={Color.RED, Color.BLACK, Color.BLUE, Color.GREEN, Color.GRAY};
int color=colors[new Random().nextInt(colors.length)];
views.setTextColor(R.id.textView1, color);
manager.updateAppWidget(provider, views);
}
}

【values/colors】
<?<resources>
<color name="logo_background">#FF0000FF</color>

</resources>

 


Android中的动画
帧动画: Frame Animation
自己查

补间动画: Tween Animation
淡入淡出动画
旋转动画
伸缩动画
平移动画


淡入淡出动画
<alpha android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="500"
android:fillAfter="true"
android:repeatCount="infinite"
android:repeatMode="reverse"
>
</alpha>


旋转动画
<rotate android:fromDegrees="0"
android:toDegrees="900"
android:pivotX="100"
android:pivotY="100"
android:duration="2000"
android:fillAfter="true">
</rotate>


伸缩动画


如何使用代码的方式设置动画:
Animation a=new AlphaAnimation(1.0, 0.1);
Animation a=new ScaleAnimation(fx, tx, fy, ty, x, y);
Animation a=new RoateAnimation(fd, td, x, y);
Animation a=new TranslateAnimation(fx, tx, fy, ty);
startAnimation(a);


完成友录项目中的通话记录模块:

 

 


day11
--------------------------------------------------------
如何对Android的电话功能进行操作

Android的电话通信机制
如何拨打电话
如何监听呼入电话
如何监听呼出电话
如何拦截呼入电话 (AIDL)


Android的电话通信机制

如何拨打电话
1>创建一个隐式意图
action=Intent_ACTION_CALL
data=Uri.parse("tel:15555555555");
2>调用startActivity启动拨号界面。
3>添加拨号的权限
android.permission.CALL_PHONE

如何监听呼入电话
1>创建一个监听器类,扩展自PhoneStateListener。
选择重写相关监听方法。
2>获取系统服务 TelePhonyManager。
getSystemService(.....);
3>调用TelePhonyManager.listen()方法监听电话状态。
4>注册权限。

如何监听呼出电话
1>创建广播接收器,用于接收系统广播。
Intent.ACTION_NEW_OUTGOING_CALL
2>在onReceive中处理广播。
常见操作,获取对方电话的电话号码。
3>在清单文件中注册该广播接收器。(代码注册)
4>处理呼出电话需要相关的处理权限。


Android中的 AIDL机制
可以实现跨进程访问第三方Service。

两个程序:
A : 客户端访问者
把服务端的AIDL文件拷贝到客户端中。
要求包名文件名必须一致。
conn=new ServiceConnection(){
onServiceConnected(xxx, IBinder binder){
AIDL接口类型=Stub.asInterface(binder);
}
};
context.bindService(intent, conn, flags);


B : 服务端service
定义AIDL接口文件,该文件中声明供客户端调用的接口方法。
Service{
onBind(){
return new Stub(){
实现AIDL接口中的方法。
};
}
}

 

 

实现拨号界面的功能:
1>触摸tvTitle弹出软键盘
2>滚动ListView 回弹软键盘
3>点击号码键盘,在tvTitle中显示内容。
4>点击退格键 删掉tvTitle中最后一位数字
5>规范电话号码显示的格式
138-8888-8888
6>点击拨号按钮,播出电话。
7>当tvTitle中的字符串更新的时候,级联更新ListView
中的数据。
List<Calllog> allData;
List<Calllog> nowData;
adapter.notifyDataSetChanged();

 

day12
------------------------------------------------
短消息相关操作:
短信发送的基本机制?
如何使用代码发送短消息?
如何使用代码接收/拦截短消息?
短消息数据库相关管理。


如何使用代码发送短消息?
1>获取用于发送短信的系统服务:SmsManager
2>调用SmsManager.sendTextMessage();方法发短信
3>发送短信需要注册权限
android.permission.SEND_SMS


SmsManager.sendTextMessage(n,null,body, p1, p2);
如何提示用户短信发送成功 (p1)
Intent i1=new Intent("SEND_OK_OR_NOT");
i1.putExtra("number", etNumber.getText().toString());
PendingIntent pi1=PendingIntent.getBroadcast(
this, 0, i1, PendingIntent.FLAG_UPDATE_CURRENT);

如何提示用户对方已经成功接收短信 (p2)
Intent i2=new Intent("RECEIVE_OK_OR_NOT");
PendingIntent pi2=PendingIntent.getBroadcast(
this, 0, i2, PendingIntent.FLAG_UPDATE_CURRENT);

当短信成功发送或对方接收短信时将会自动的执行
这两个pendingIntent。


如何使用代码接收/拦截短消息?
1>编写一个广播接收器,接收系统广播:
android.provider.Telephony.SMS_RECEIVED
2>重写onReceive方法,在该方法中获取短信内容。
3>在清单文件中注册权限。接收短消息的权限。

 

----------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------


day13
【Html】
------------------------------------------------------
服务端基础 tomcat jsp
HttpClient相关API JSON
音乐播放器
复习 优化
通知 service
ContentProvider
联系人提供程序 友录
Intent详解 BroadcastReceiver
媒体提供程序 重构音乐播放器
AppWidget 动画 友录
电话模块
短信模块


Service
如何编写Service。
startService 生命周期
bindService 生命周期
IntentService
onHandleIntent(){}

ContentProvider
跨进程数据共享。
如何编写ContentProvider。
如何访问ContentProvider。
Uri

BroadcastReceiver
android中的广播机制。
如何编写广播接收器。
广播的分类。每一类什么特点。

Activity
界面的组织结构。
activity的生命周期。
activity内部的各种控件。
布局。
activity的启动模式。


【IntentService】
http://blog.csdn.net/guolin_blog/article/details/42238627
在4月15的那个文件夹中 130 , 169

--------------------------------------------------------
HTML基础

什么是HTML?
超文本传输标记语言。

HTML用什么开发? H5Builder
HTML由谁解析并且执行显示?

浏览器
google chrome
firefox
ie
Opera

猎豹
360
UC
safari
。。。。。。

浏览器大战

NetScape 网景公司
88%

Microsoft 微软
IE 98%
在windows操作系统中绑定IE。免费


Mozilla基金会
FireFox

-------------------------------------------------------
如何编写HTML文档:
HTML的基本结构
<html>
<!-- 主要用于定义当前html文档的基本信息 -->
<head></head>
<!-- 主要用于定义当前文档中的各种组件 -->
<body></body>
</html>

如何编写一篇html?
新建一个html文档,后缀名必须是 .html


html中的常见标签:
换行标签:
<br/>

分隔线标签:
<hr width="" align=""/>
width: 宽度 单位:px
100px
50% 占用父标记宽度的50%
align: 对齐方式
left / right / center


段落标签:
<p> 段落的内容 </p>

样式相关的标签:
<b></b>
<i></i>
<s></s>


图片标签:
<img src="" alt="" title="" />
alt/title: 当鼠标悬停到图片上时 显示的提示文本
src: 目标图片的路径
width: 图片的宽度 px
height: 图片的高度 px

绝对路径:
基于操作系统的绝对路径:
windows
以盘符开头的路径成为绝对路径。
c: d: e: f:
linux / unix / MacOs
以根目录开头的路径成为绝对路径。
/xxxx/xxx/xxxx.jpg
基于网络的绝对路径:
以http://开头的路径
http://www.baidu.com/images/logo.png
http://tts6.tarena.com.cn/verifyCode/getCode.do

相对路径: //相对路径前面不用加“/”
<img src="lyf01.jpg"/>
day13/first.html
day13/lyf01.jpg // file:///E:/workspace_1503/Html/Html_File.html


浏览器支持的图片的格式:
1>JPEG 适合做大图 不支持透明色
2>PNG 颜色鲜艳 支持透明色
3>GIF 动态图 支持透明色


超链接标签:
<a href="" title="" alt=""> text </a>
text: 链接文本
href: 该链接指向的目标路径
# 跳转到当前页面中的某个锚点
javascript:;
title/alt: 鼠标悬停后的提示文本

图片链接:
<a href="链接的目标地址">
<img src="图片的路径"/>
</a>


表格相关标签
表格的使用场景:
早期我们使用表格做网页的排版布局。
现在表格常用于呈现二维数据。

表格的基本结构:
<table> 描述一个表格
<tr> 描述一个表格行
<td></td> 描述一个单元格
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>

表格相关的属性:
table:
width: 宽度
height: 高度
align: 对齐方式
border: 边框宽度
cellpadding: 单元格的内边距
cellspacing: 单元格的外边距

td:
rowspan: 按行合并单元格
colspan: 按列合并单元格

第二套表格标准:
<table>
<caption></caption> 表格标题
<thead>tr td</thead> 表头
<tbody>tr td</tbody> 表体
<tfoot>tr td</tfoot> 表脚
</table>


html表单标签:
什么是表单?
用于收集用户输入的数据,并且在用户点击
提交按钮时,把这些数据进行整理提交给
服务器。

表单标签:
<form action="url" method="get">
包含多个表单组件
</form>

表单组件:
文本框 <input type="text" />
密码框 <input type="password" />
单选按钮 <input type="radio" />
多选框 <input type="checkbox" />
提交按钮 <input type="submit" value="登录" />
重置按钮 <input type="reset" value="重置" />
普通按钮 <input type="button" value="普通" />

下拉列表框
<select> 描述一个下拉框
<option>河北省</option> 描述一个下拉项
<option>河北省</option> 描述一个下拉项
<option>河北省</option> 描述一个下拉项
</select>

多行文本域
<textarea rows="" cols="" >
</textarea>

 


day14
--------------------------------------------------------
HTML表单提交规则:
只有含有name属性的表单组件才可以在提交时
传递参数。
/webbasic/day14/regist.do?gender=on

向服务器传递的参数规则:
参数名:name属性
参数值:value属性
/webbasic/day14/regist.do?name=zs&pwd=123456&gender=m&aihao=c&aihao=h&aihao=w&pro=黑龙江省&jj=22222222222222222222222222222
/webbasic/day14/regist.do?name=zs&pwd=1234&gender=f&aihao=c&aihao=l&pro=jl&jj=222

表单组件默认值的规则
<input type="text" value="默认值"/>
单选按钮的默认选中:
<input type="radio" value="m" checked="checked"/>
多选框的默认选中:
<input type="checkbox" value="m" checked="checked"/>
下拉列表框默认选择:
<select>
<option selected="selected">---请选择---</option>
</select>

HTML列表相关标签

列表标签的基本结构:
<ul> 用于描述一个列表
<li></li> 用于描述一个列表项
<li></li>
<li></li>
<li></li>
</ul>

----------------------------------------------------
CSS 级联样式表
CSS 主要用于控制HTML页面中的排版与布局。
页面组件的样式渲染。

CSS代码实现了页面中结构逻辑与显示逻辑
代码的分离,便于代码的维护。

CSS代码的基本结构:
css选择器 {
css样式属性名:属性值;
css样式属性名:属性值;
css样式属性名:属性值;
}

CSS选择器:
可以选出当前页面中一个或多个标签。然后
使用css样式属性对这些标签添加样式。

通配符选择器:
匹配当前文档中的所有标签。
* { color: red; }

如何给html文档编写css?
1>编写外部css文档。要求后缀名必须是.css
2>在html中用<link> 标签引入并应用该css文档。
<link type="text/css" rel="stylesheet"
href=""/>

标签选择器:
可以选出当前文档中符合标签名称要求的所有
标签.
选出当前文档中所有的p标签
p { }
li { }
a { }


id选择器:
选出当前文档中符合id属性值要求的一个标签:
<p id="p1"> </p>
#p1 { .... }


class选择器(类选择器)
选出class属性名符合要求的多个标签。
我们可以认为这些标签应用同一类样式。

定义一类样式:
.className { ... }
让一些标签应用这一类样式
<div ></div>

分组选择器
把多个选择器选出的标签当成一组,然后
统一添加样式。
p, .div, span, #id { xxx }

派生选择器
通过父标签找到子标签,然后给子标签添加
样式。
<div>
<span></span>
</div>
<span></span>

.div .span { }


CSS的样式属性:
布局属性
css的box模型

外边距: margin
margin: 10px; 四个方向都设置外边距为10px
margin: 10px 20px; 上下外10px 左右外20px
margin: 0 auto; 该组件将会基于父容器居中.
margin: 1px 2px 3px 4px; 上右下左
margin-left:
margin-right:
margin-bottom:
margin-top:

内边距: padding
padding: 10px; 上下左右内边距
padding: 10px 20px;
padding: 1px 2px 3px 4px; 上右下左
padding-left:
padding-right:
padding-bottom:
padding-top:


背景属性 background
background-color: 背景颜色
red | blue | green .....
#000000 #ffffff
#aabbcc #abc
background-image: 背景图片
url("../images/xxx.jpg")
background-repeat: 背景图片的平铺方式
repeat: 默认 双向平铺
repeat-x: x轴平铺
repeat-y: y轴平铺
no-repeat: 不平铺
background-position: 背景图像的定位
background-position:-xpx -ypx;


字体属性 font
font-size 字体大小
font-family 字体 黑体
font-weight 磅值 (粗细)
lighter | normal | bold | bolder
100 ~ 900
font-style
normal: 普通样式
italic: 斜体字

文本属性 text
color:
text-align: 文本对齐方式
text-decoration: 文本的装饰
line-height: 行高

边框属性 border
border:1px solid black;
border-width: 边框宽度 px
border-left-width:
border-right-width:
border-top-width:
border-bottom-width:
border-style: 边框样式 solid ....
border-left-style:
border-right-style:
border-top-style:
border-bottom-style:
border-color: 边框颜色 #aaa
border-left-color:
border-right-color:
border-top-color:
border-bottom-color:

列表属性
ul li
list-style:none;

css复杂属性:
display: 用于控制组件的显示与隐藏
none: 隐藏
block: 把行级标记按块级标记显示
只有块级标记才可以设置width与height。

float: 浮动
可以块级标记横向排列。
left 浮动后往左放
right 浮动后往右放

 


day15
----------------------------------------------------------
css样式之position
position: 用于组件的定位
static
absolute
relative

如果设置一个组件的position=absolute
那么该组件将会脱离默认的文档流,形成
一个绝对定位的层。我们可以使用z-index
属性控制组件的层标。数字大的将会覆盖
z-index小的组件。
我们可以使用top和left属性控制组件的位置。
top和left在定位的时候需要有相对参照物,
先寻找父标签,如果父标签中有:
position=relative属性那么则相对于父标签。
如果没有则继续寻找祖先标记。直到
找到body,则相对参照物为body。

 

-------------------------------------------------------------
Javascript 简称 JS
什么是JS?
javascript是网景公司开发的一款基于浏览器
运行的弱类型脚本语言。

javascript的作用:
1>网页中的数据验证
2>操作网页实现动态效果。
3>访问浏览器的基本属性信息。
4>实现ajax。
5>与移动端接口进行交互。

js的特点:
1>javascript是一门类c的语言。
2>javscript支持基于对象编程但不是纯粹的
面向对象语言。
3>javascript是一门弱类型语言。
var i;
i=2;
i="";
i=true;

javascript的组成部分:
ECMAScript规范
定义js的语法相关规范。(基础)
DOM
Document Object Model 文档对象模型
BOM
Browser Object Model 浏览器对象模型
提供了一些API用于访问浏览器的信息。


如何编写Javascript代码?
1>编写外部javascript文档(*.js),并且在文档
中编写javascript代码。
2>在html页面中使用<script>标签引入外部js文档。
<script src="路径" type="text/javascript"></script>


JavaScript的基本数据类型
java:
int char long byte short double float boolean
js:
number: 用于描述数字
string: 用于描述字符串
boolean: 用于描述true false
null:
undefined: 未定义

数据类型之间的转换:
数字与字符串之间的转换:
数字 -> 字符串:
var num=888;
var str=num.toString();
var str=num+"";

字符串 -> 数字:
var str="8888.88";
var number=parseInt(str);
var number=parseFloat(str);

var str="8888abc";
var number=parseInt(str); --> 8888

boolean类型对其他数据类型的解释规则:
if(isMarried){
}

js引擎会把非0数字解释为true,0为false。
把非空字符串解释为true,""为false。
把null / undefined解释为false。


运算符
数学运算符
+ - * / % ++ -- += -=
关注:/
var str="88";
alert(str/8);

逻辑运算符
&& || !
if(a && b){ }
if(a && b){ }

比较运算符
> < >= <= != == ===
== :比较两个变量的内容
str1==str2
===: 先比较两个变量的类型,如果一致则
再次比较两个变量的内容。
str1===str2

三元表达式
isMarried ? "" : "";

String str1="abc123";
String str2="abc"+"123";
String str3="abc";
String str4="123";
String str5=str3+str4;
String str6="abc"+123;

str1==str2 true
str1==str5 false
str1==str6 true

条件分支语句
if(){
}else if(){
}else{ }

switch(){
case 0: break;
case 1: break;
default:
}

流程控制语句
while(){
break;
continue;
}

do{
....
}While();

for(i=0; i<ary.length; i++){
break;
contunie;
}

JS的常用API:
Math: 数字相关
String: 字符串相关


案例:
验证13位条形码
693335100007 5
1>求出前12位奇数位数字之和 633100=13
2>求出前12位偶数位数字之和 935007=24
3>把 "前12位奇数位数字之和" 与
"偶数位数字之和的3倍" 相加。13+72=85
4>求结果的个位数 5
5>用10减去这个个位数 5
6>再取结果的个位数 5

function check(){ var code="693335100007"; }


JS的Array对象
特点:
js的数组对象长度可变。
js的数组对象中元素的类型可以不一致。

如何声明数组?
var ary=[100, "hello", true];
var ary=new Array();
如何访问数组的长度?数组元素?
ary.length 数组的长度
ary[1] 获取下标为1的元素
如何修改相应index位置的元素?
ary[1]="hello world.";
如何添加元素?
如何删除元素?
API查去

18位身份证号码验证:
12345678901234567 8

 

day16
------------------------------------------------
双色球案例重构

认识Array相关的API:
Java:
int[] ary;
Arrays.sort(ary, new Comparator<Integer>(){
int compareTo(Integer i1, Integer i2){
return i1-i2;
}
});
List<Integer> list;
Collections.sort(list, new Comparator<Integer>(){
int compareTo(Integer i1, Integer i2){
return i1-i2;
}
});

List<Person> list;

JS的函数:
function name(arg1, arg2, arg3){
alert(arg1);
return arg1;
}
我们也可以使用js中内置的arguments数组接收参数:
check(200, 300);
function check(){
return arguments[0] == arguments[1];
}
add(32,4,4,57,56,3,423,5,35,6757,56,3,45,2);
function add(){
sum;
for(i=0; i<arguments.length; i++){
sum+=arguments[i];
}
return sum;
}

我们也可以使用js中内置的arguments数组接收参数:
argments将会封装调用传递过来的各种参数。
js的函数可以有return。如果没有return,调用
者获取的函数的返回值将会是undefined。
js在调用函数的时候仅仅检测函数名,
如果js中有两个函数名称相同的函数,不检测
参数列表,后一个函数将会有效。


------------------------------------------------------
【DOM】 Document Object Model

对HTML标签相关操作:
查询标签
var eleObj=document.getElementById("id");
var ary=document.getElementsByTagName("div");
修改标签
<img src=""/>
<div>文本文字</div>
<div ></div> css内联样式
<input value=""/>

img.属性名
div.innerHTML 修改内容文本
div.style.xxxx 修改css样式
input.value 访问并且修改input标签的value

js表单验证:
用户在填写完表单组件后,需要使用js对
表单中的数据格式进行验证。并且给用户
提示。
如果表单中有一个表单组件格式不正确,则
点击提交按钮时,阻止表单的提交。


[0-9] \d
[a-zA-Z]
[a-zA-Z0-9_] \w

\d{10} 数字字符连续出现10次
\d{1,10}
\d{1, }
\d{, 10}

\d* 0到多次
\d+ 1到多次
\d? 0或1次
/[0-9]+/

阻止表单的提交:
当在点击提交按钮时,触发onsubmit事件。
<form onsubmit="return false;"></form>
表单将阻止提交。

增加标签
var childNode=document.createElement("span");
fatherNode.appendChild(childNode);
<div>
<span>aaaaaa</span>
<span>aaaaaa</span>
</div>

fatherNode.insertBefore(newNode, refNode);
<div>
<span>old</span>
</div>

删除标签
removeChild()
replaceChild()


级联下拉列表
创建<option>
把<option>追加到<select>标签的子标签中

1>监听省份列表的onchange事件
2>获取选择的省份
3>根据省份获取城市列表
4>把所有的城市构造成option添加到select中。

河北省
山东省
山西省
河南省

var data=[["石家庄","邯郸","保定","秦皇岛"],
["青岛","济南","威海"],
["太原", "长治", "运城", "大同"],
["郑州", "开封","南阳", "安阳"] ];


【BOM】 浏览器对象模型

alert()


JS定时器相关API:

每100毫秒执行一次。(周期性执行)
window.setInterval(function(){},100 );

100毫秒后执行一次。(仅执行1次)
window.setTimeout(function(){}, 100);

 


day17
---------------------------------------------------------------
javascript的面向对象基础
封装
继承
多态

如何模拟创建类型?
模拟创建类型:
function Point(){
}
var p=new Point();

如何创建类型的实例?

1>使用模拟类型创建Point对象
function Point(x, y){
this.x=x;
this.y=y;
this.say=function(){ };
}
var p=new Point(10, 20);
alert(p.x);
alert(p.y);
p.say();

2> 使用Object 创建临时对象:
var obj=new Object();
obj.name="zhangsan";
obj.age=20;
obj.sayHello=function(){ alert("hello!"); };

alert(obj.name);
alert(obj.age);
obj.sayHello();

3>使用json的语法创建js对象:
var obj={ "name":"zs", "age":30,
"aihao":["吃","喝"],
"school":{ "name":"清华", "loc":"北京" } };
alert(obj.name);
alert(obj.aihao[1]);
alert(obj.school.name);


Javascript中的继承的实现:
prototype chain 原型链

function Point(){
}
Point.prototype.x=10;
Point.prototype.y=20;

var p=new Point();

--------------------------------------------------------
HTML5
是HTML的一个新版本。

HTML5新增的主体标签:
主要用于替代老式页面中的div。

header 定义页面中的头部
footer 定义页面中的底部
nav 定义页面中的导航部分
aside
article
section


HTML5新增的非主体标签:
<meter>
<meter max="200" min="0" value="0"
low="60" high="150" id="meter"
></meter>

<progress>
<progress max="200" value="100" ></progress>

HTML5新增的表单标签
<form>
</form>

<input type="email" name=""/>
<input type="url" />
<input type="number" />
<input type="range" />
<input type="time" /> 时间相关的表单组件
<input type="week" />
<input type="month" />
<input type="date" />
<input type="datetime" />
<input type="search" />
<input type"color" />

/html5_day17/newtag.html?email=x%40x.com&url=http%3A%2F%2Fwww.baidu.com&number=7&range=15&time=00%3A01&week=2015-W25&month=2015-06&date=2015-06-18&datetime=datetime&search=search&color=%23ff0000


input表单标签的通用属性:
placeholder
pattern 匹配的正则表达式
required 如果设置了该属性,则该input不能为空


Canvas画布
canvas元素是html5新增的用于在页面中绘制
图形图像的标签。绘制的方式需要使用js。

如何使用canvas?
<canvas id="canvas"></canvas>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx对象提供了各种绘图的方法,我们可以调用
这些方法对canvas进行绘制。

ctx.fill; 设置填充时的颜色
ctx.fillRect(x, y, width, height); 填充矩形

设计:
Node 描述一个画布上的节点
i
j
Worm 描述一个蛇
nodes (Node数组)
step() 向前走一步
Stage 描述一个舞台
width 50
height 50
worm
print() 用于绘制舞台的内容

 


day18
----------------------------------------------------------
HTML5新增媒体相关标签
视频:
<video></video>

html5支持的视频格式:
ogg: video/ogg
mp4: video/mp4
WebM:

video标签的常见属性:
autoplay: 自动播放
controls: controls 是否显示控制栏
loop: 循环
preload: 预加载
src: 数据源
width: video标签的width
height: video标签的height


Javasript对video对象的支持
HTML5提供了一些js的api来操作video标签:
var video=document.getElementById("video");
video.属性
currentSrc 当前设置的数据源
currentTime 当前播放的时间进度
videoWidth 视频的宽度
videoHeight 视频的高度
duration 视频的时长
volume 视频的音量
width 标签的宽度
height 标签的高度

video.方法()
play() 播放
pause() 暂停


音频:
<audio></audio>


audio标签的常用属性
autoplay: 自动播放
controls: controls 是否显示控制栏
loop: 循环
preload: 预加载
src: 数据源

html5支持的音频格式
ogg audio/ogg
mp3 audio/mpeg
wav


JS对audio标签的支持

 

-----------------------------------------------------------
CSS 3.0

CSS3新增的选择器

CSS3 边框属性
CSS3 背景属性
CSS3 文本属性
CSS3 的过渡属性
CSS3 的变换属性
CSS3 的动画


CSS3新增的选择器
[attribute^=value] a[src^="https"] 选择其 src 属性值以 "https" 开头的每个 <a> 元素。 3
[attribute$=value] a[src$=".pdf"] 选择其 src 属性以 ".pdf" 结尾的所有 <a> 元素。 3
[attribute*=value] a[src*="abc"] 选择其 src 属性中包含 "abc" 子串的每个 <a> 元素。 3

:empty p:empty 选择没有子元素的每个 <p> 元素(包括文本节点)。 3
:target #news:target 选择当前活动的 #news 元素。 3
:enabled input:enabled 选择每个启用的 <input> 元素。 3
:disabled input:disabled 选择每个禁用的 <input> 元素 3
:checked input:checked 选择每个被选中的 <input> 元素。 3

CSS3 边框属性
border: 1px solid black;
border-radius 用于设置圆角边框
border-radius: 5px;
border-radius: 50%; 椭圆
box-shadow 用于设置边框的投影
box-shadow: apx bpx cpx d;
a / b: 定义阴影的偏移位置
c:定义阴影的模糊程度
d: 定义阴影的颜色

CSS3 背景属性
background-size: 背景图片的大小
background-size: widthpx heightpx;
background-size: contain;
background-size: cover;
-webkit-background-size: contain;
background-origin:
绘制背景图片时的起始位置:
border-box
padding-box
content-box

CSS3 文本属性
text-shadow: 文本的投影
text-shadow: width height px #fff;
width 水平阴影的距离
height 垂直阴影的距离
px 模糊距离
#fff 投影的颜色

CSS3 的过渡属性 transition
通过css样式的设置,我可以在不使用flash
和js的情况下把一个控件从一个状态变为
另外一个状态。

1>在组件初始化的状态时定义过渡动画参数:
transition: all 2s ease 1s;
all: 过渡的属性
2s: 过渡时的执行时间
ease: 过渡时的动画时间曲线
1s: 过渡动画执行的延时

transition-property:
transition-duration:
transition-timing-function:
transition-delay:

以上所有属性需要根据不同的浏览器设置相应
的过渡属性。

CSS3 的变换属性
transform变换属性

scale: 伸缩
translate: 平移
rotate: 旋转

scale: 伸缩
div:hover{
transform: scale(2, 2);
transform: scale(0.5);
}

translate: 平移
div:hover{
transform: translate(x, y);
}

rotate: 旋转
div:hover{
transform: rotate(720deg);
}

CSS3 的动画

 

day19
--------------------------------------------------------------
CSS3 动画
css3的动画可以使标签从一个css状态逐渐
变为另外一种css状态。
我们可以使用@keyframes规则来实现css3的
动画效果。

1>使用@keyframes规则定义动画效果:
@keyframes anim{
from {定义组件开始时的css样式}
to {定义组件结束时的css样式}
}
@-webkit-keyframes anim{ ... }
2>给组件设置css样式,使用并执行anim动画:
div:hover{
animation: anim 3s;
-webkit-animation: anim 3s;
}


我们还可以使用以下方式定义动画规则:
@keyframes anim2{
0% {}
25% {background-color: #1E90FF;
transform: rotate(30deg);
margin-left: 0px; }
50% { background-color: forestgreen;
margin-left: 600px;
transform: rotate(0deg); }
100% {
margin-left: 0px;
background-color: coral;
transform: rotate(-360deg);
}
}


CSS3的Media query 响应式设计

设计出的响应式页面需要适配3类屏幕
480 ~ 600
600 ~ 800
800以上
需要为每一类都制定一套css样式

<link rel="" href="" type=""
media="screen and (min-width:800px) "/>
<link rel="" href="" type=""
media="screen and (max-width:800px) and (min-width:600px) "/>
<link rel="" href="" type=""
media="screen and (max-width:600px) and (min-width:480px) "/>


Android中的WebView的使用:

WebView是Android手机端的一个控件。内置
webkit内核。

webView.loadUrl("file:///android_asset/www/x.html");

WebSettings: 封装了webview的基本设置
settings.setJavascriptEnabled(true); //启用js

WebView的两大属性:
WebViewClient
WebChromeClient

//WebViewClient
webView.setWebViewClient(new WebViewClient(){
//重写父类的url加载方式
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
//WebChromeClient //重写弹窗 //AlertDialog(提示对话框)
webView.setWebChromeClient(new WebChromeClient(){

});


WebView中js与Android中的程序之间的交互

1>
android程序调用webView中的javascript函数:
int num=100;
webView.loadUrl("javascript:doClick("+num+")");
String str="hello";
webView.loadUrl("javascript:doClick('"+str+"')");

2>
webView中js如何调用Android中的代码?
html:
window.接口名称.方法名();
Android:
webView.addJavascriptInterface(
new MyObject(), 接口名称);
class MyObject{
@JavascriptInterface
public String 方法名(){
return xx;
}
}

 


day20
---------------------------------------------------------
【Jquery框架】
jquery-x.x.x.x.js
jquery是javascript的一款前端框架。

使用jquery的基本步骤:
1>在html页面中引入jquery.js
<script src="js/jquery.js"/> (路径问题)
2>jquery的基本使用方式:
<script>
//当文档加载完毕后执行
//$(document) : 把文档对象包装成一个jquery对象
//调用jquery对象的ready方法添加事件监听。
//ready方法中的匿名函数将会在文档对象
//加载完毕后执行
$(document).ready(function(){
给页面中的某个标签添加事件监听
$("a").click(function(){
alert("这是一个单纯的链接");
});
});
</script>

属性操作:
$("a").attr("href");
$("a").attr("href", "设置");

css样式操作:
$("a").css("color");
$("a").css("color", "设置颜色值");

内容文本操作:
$("a").text();
$("a").text("设置innerHTML文本");

input的value属性操作:
$("input").val();
$("input").val("设置input的value值");

 

day21
------------------------------------------------------------
Jquery与Ajax
什么是ajax?
ajax是网页中使用javascript异步发送http请求的
方式。基于javascript的

jquery把这些繁杂的原生的ajax代码做了封装,
我们可以使用jquery提供的方便的API实现ajax
操作。


微信广告页的制作

fullpage.js

fullpage页面的基本结构:
<link href="fullpage.css">
<script src="jquery.js">
<script src="fullpage.js">
<body>
<div id="fullpage">
<div ></div>
<div ></div>
<div ></div>
</div>
</body>

文档:
https://github.com/alvarotrigo/fullPage.js#fullpagejs

实例
通过 AJAX 加载一段文本:
jQuery 代码:
$(document).ready(function(){
$("#b01").click(function(){
htmlobj=$.ajax({url:"/jquery/test1.txt",async:false});
$("#myDiv").html(htmlobj.responseText);
});
});
HTML 代码:
<div id="myDiv"><h2>Let AJAX change this text</h2></div>
<button id="b01" type="button">Change Content</button>


美一页项目搭建

服务端:
1>初始化数据库。 h5page.sql
先执行命令:set names gbk; 防止编码问题。
2>创建服务端程序 myy_server并且把源码粘贴进来。
3>打包: myy_server.war
4>部署: tomcat/webapps目录
5>启动服务端

客户端:
1>创建新的客户端程序 MYY
修改客户端程序所访问的BASE_URL的ip地址:
com.tarena.myy.util.GlobalConsts.BASEURL=".......";
2>把源码复制粘贴到MYY项目中:
res / src / libs / AndroidMenifest.3>安装应用 运行。



美一页业务实现:
1>
实现MainActivity的UI
实现右上角+的监听,点击后跳转到ChooseActivity
选择要使用的模版。
2>
实现ChooseActivity中的显示模版的主要业务。
数据源: 访问tomcat:
url:
http://ip:port/myy_server/loadModules.jsp
method:
GET
params:
NULL
return:
[
{"content":"<div class=\"section\"><img src=\"images/module_01.png\" height=\"100%\" style=\"display:block; margin:0 auto;\"/><\/div>","id":1,"name":"图片单页","snapshot":"images/module_01.png"},
{"content":"<div class=\"section\"><img src=\"images/module_02.png\" height=\"100%\" style=\"display:block; margin:0 auto;\"/><\/div>","id":2,"name":"图片单页","snapshot":"images/module_02.png"},
{"content":"<div class=\"section\"><img src=\"images/module_03.png\" height=\"100%\" style=\"display:block; margin:0 auto;\"/><\/div>","id":3,"name":"图片单页","snapshot":"images/module_03.png"},
{"content":"<div class=\"section\"><img src=\"images/module_04.png\" height=\"100%\" style=\"display:block; margin:0 auto;\"/><\/div>","id":4,"name":"图片单页","snapshot":"images/module_04.png"}
]

 

业务实现2:
1>选择其中一个模版,获取选择的模版对象,
启动新的EditActivity。传递选中的模版对象。
2>构造EditActivity的界面。
RelativeLayout
ViewPager + Fragment + WebView
3>接收module参数,根据参数module对象构造
Fragment对象,并且更新ViewPager
4>Fragment的写法:
加载布局,布局中只有一个WebView。
webView加载网页模版:
http://ip:port/myy_server/module.jsp
调用页面中的js函数:appendpage(content)
把当前需要加载的模版的content属性追加
到webView中显示。
5>点击EditActivity中的加号添加一个新的模版,
重新跳转到ChooseActivity。
startActvityForResult()
6>当用户选择了某个模版后,调用setResult方法
传回EditActivity,我们需要把该module追加
到module集合中,更新ViewPager的显示。

 

业务实现3:
1>点击左上角的修改图标修改模版的背景图片。
使用隐式意图启动用于选择图片的Activity。
当图片选择完成,将会返回该图片的uri。
2>onActivityResult(){}
接收到选择的图片后,根据图片的uri,
使用隐式意图启动用于切割图片的Activity。
并且传递切割图片时所需要的各种参数。
3>onActivityResult(){}
接收到切割图片成功的返回结果后,把
切割过后的图片上传到服务器:
url:
http://ip:port/myy_server/upload.jsp
method:
post
params:
uploadfile: 文件对象
return:
服务端保存后将会返回:
{result:ok, path:images/xxxxxxxxxxxx.jpg}
4>更新模版中的图片信息:
更新ViewPager中的内容。


业务实现4:
1>点击播放大按钮,生成fullpage页面的主体
html部分。遍历所有的模版把所有模版中的
内容都整合在一起。并且提交给服务器保存:
url:
http://ip:port/myy_server/savepage.jsp
method:
post
params:
content: html主体内容
return:
{ result:ok , genId: 生成的fullpage页面的主键id }

2>跳转界面到ShowH5Activity显示整张页面:
在跳转时需要传递页面id
3>在ShowH5Activity中接收id的参数,然后向
服务端发送请求,获取相应页面的返回值:
webView.loadUrl("http://ip:port/myy_server/h5.jsp?id=xxx");

 

【去图库中选择图片】
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*"); // Or 'image/ jpeg '
startActivityForResult(intent, RESULT_PICK_PHOTO_NORMAL);

 


------------------------------------------------------------------------------------------------------------------------------------------------------------------
【第四个老师】
质量 成本

1.架构师 1
2.设计师 10
3.程序员 100

进入聚合网 数据
www.juhe.cn

Android项目下载
www.javaapk.com

架构模式(mvc,多层)
设计模式(23个设计模式)

 


github:全世界最大的开源网站
open-open.com 最大的中文开源网站


【切换屏幕】 //生命周期不会重起
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
int orientation = newConfig.orientation;
super.onConfigurationChanged(newConfig);
}
<activity
android:name=".view.PrivateChatActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation|screenSize">
</activity>
横竖屏切换时候activity的生命周期?
不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,
设置Activity的android:configChanges="orientation|keyboardHidden"时,
切屏不会重新 调用各个生命周期,只会执行onConfigurationChanged方法


【屏幕尺寸】
int screenWidth = activity.getResources().getDisplayMetrics().widthPixels;

 

【结束进程】
System.exit(0);

 


【UML】 【MyEclipse】
前三
类图
Class
子类 拉向 父类
接口 拉向 子类

时序图
Sequence

活动图
Activity

后四
状态图
statechart

用例图
Use Case

节点图
Deployment

协助图
Collaboration

 


【当前版本】
public static String getCurrentVersion(Context context)
throws NameNotFoundException {
PackageManager manager = context.getPackageManager();
String packageName = context.getPackageName();
PackageInfo packageInfo = manager.getPackageInfo(packageName, 0);
return packageInfo.versionName;
}

【安装App】
private void installApk(String apkPath) {
//用代码安装apk
Intent intent=new Intent(Intent.ACTION_VIEW);
Uri data=Uri.fromFile(new File(apkPath));
//type:表示的是文件 类型
//mime,定义文件类型 text/html ,text/ String type="application/vnd.android.package-archive";
intent.setDataAndType(data, type);
startActivity(intent);

}

 

 


http://news.sina.com.cn/c/2014-05-05/134230063386.shtml
AA用车:智能短租租车平台
手机腾讯网
07-05 06:46:24

 


【include】
<FrameLayout
android:id="@+id/tool_bar_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >

<include
android:id="@+id/tool_bar"
layout="@layout/tool_bar" />
</FrameLayout>

//tool_bar.<LinearLayout android:layout_width="fill_parent"
android:layout_height="40.0dip"
android:background="@color/toolbar_bg"
android:orientation="vertical" >

<View
android:id="@+id/toolbar_divider"
android:layout_width="fill_parent"
android:layout_height="0.5dip"
android:background="@color/detail_divider_day" />

<FrameLayout
android:layout_width="0.0dip"
android:layout_height="fill_parent"
android:layout_weight="1.0" >

<ImageView
android:id="@+id/action_favor"

android:src="@drawable/ic_action_favor" />
</FrameLayout>

</LinearLayout>

【tomcat服务器】
短连接

【OpenFire】
适用于聊天的服务器,长连接

 

【SVN Server】 //使用http协议进行传送,可以在互联网上使用,开发项目用
在开始/所有程序那儿打开

xp系统
telnet 172.16.4.165 443 //dos //跳转到全黑

把插件加入到eclipse目录内,关闭eclipse,再打开 //features和plugins放入dropins文件,其他的show view svn资源库 //svn-1.6.17.zip
http://blog.csdn.net/spring123tt/article/details/6709260
记得要用工具把已经存在的.svn文件(如果存在的话)删除掉

可以先检出整个svn内的所有项目作为app目录,在eclipse中,然后把你自己想导入到svn中的项目放入app目录中(记得删除.svn文件)
之后再提交整个app项目,就可以把你想导入svn中的项目导入进去,之后就可以检出了。

https://172.16.4.165/svn/1503/ //下面的,右上角+

账号 //在svn中自己建的
密码

在自己的项目中右键,team-->share project-->在大白框中填第一次提交,勾选所有的。


改自己的部分,然后只能提交自己改了的部分进行提交

team更新

如果无法更新,可以先断开连接,再删除项目,再重新检出一次

提取之前的版本可以在“显示历史资源记录”中,右键以前的,选第二项“从修订版创建分支/标记”,然后改一下“到url”的名字如:lipeineng2
这样会以以前的版本创建一个新的项目,至于在原项目中返回以前的版本我不知道

 

 

【NDK】
路径不要有中文
NDK插件:用于开发Android NDK的插件,ADT版本在20以上,就能安装NDK插件,另外NDK集成了CDT插件
Android官网下载最新的NDK,注:NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版。
http://www.cnblogs.com/yejiurui/p/3476565.html //NDK环境搭建 这种可以在eclipse中直接通过clean来编译
http://blog.csdn.net/asmcvc/article/details/9311541 //直接用dos

要注意的有application.mk中的NDK_TOOLCHAIN_VERSION=4.6 的版本号,要看你自己的NDK的android-ndk-r9\toolchains中是不是有这个版本
application.mk中的APP_PLATFORM := android-14,你的AndroidManiFest中的minSdkVersion="14" 两个最好相等
不用像jdk和sdk那样在系统环境变量中配置

C:\Users\Administrator>d:
D:\>cd D:\mywork\android-ndk-r8\samples\hello-jni
D:\mywork\android-ndk-r8\samples\hello-jni>D:\mywork\android-ndk-r8\ndk-build.cmd
Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so

D:\mywork\android-ndk-r8\samples\hello-jni>


【cygwin】
使用最新ndk,直接抛弃cygwin,以前做Android的项目要用到NDK就必须要下载NDK,
下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配置编译器,环境变量,特别麻烦,新版就不需要了

和ndk在一个子目录下,安装时,第一步选第三项
其他的就是下一步
出现一个警告,不用管
把devel的default改为install,其他默认

进入c盘的安装后的目录,发现home空的,点击后面的Cygwin.bat文件,会在home生成文件

在.bash_profile文件用Editplus打开在最后粘贴上
#NDK=/cygdrive/d/android-ndk-r5c-windows/android-ndk-r5c

之后再加上自己的ndk的目录(其子目录要有build) //D:\ndk1503\android-ndk-r5c-windows\android-ndk-r5c //大写变小写,不要有空格,斜杠要反过来
NDK=/cygdrive/d/ndk1503/android-ndk-r5c-windows/android-ndk-r5c
export NDK

再点击Cygwin.bat,输入 cd $NDK
ls

可以调用c语言

 


【Junit】
测试,单元测试

Junit右上角倒数第二个可以导出


【证书】 //http://www.jb51.net/article/37103.htm
使用Eclipse导出带签名的apk
Location android.keystore smart.keystore
password //密码 hyhotelservice
confirm //确认 hyhotelservice

alias //别名 androiddebugkey_platform
validity //有效性 1000
first and last name liming
organizational unit 组织单位 HY
organization JD
city or locality SZ
state or province //国家或省份 GD
country code //国家代码 CN

换到E盘
e:
jarsigner -verify -verbose -certs tsinged.apk

【ant】打包 //失败 //testAnt2文件路径不要有中文
环境变量
ANT_HOME
D:\Android\eclipse\plugins\org.apache.ant_1.8.2.v20120109-1030 //ant根路径

----------------------------------------
sdk.dir=D:\\Android\\sdk
project.dir=E:\\WDJDownload\\testAnt2
------------------------------------------
application.package=com.example.testant2
ant.project.name=testAnt2
key.store=E:/WDJDownload/testAnt2/key.keystore
key.store.password=123456
key.alias=123456
key.alias.password=123456

appStore=uc,qq,360
out.absolute.dir=d:/1503/class
gos.path=d:/1503/apk
java.encoding=utf-8
app_version=1.0.0


【gradle多渠道打包】 //成功
配置环境变量
GRADLE_HOME E:\WDJDownload\gradle-1.10-all\gradle-1.10 //解压出来的一部分,路径最好不要有中文
PATH %WPS_HOME%;%JAVA_HONE%\bin;%PATH%;D:\Android\sdk\platform-tools;D:\Android\eclipse\plugins\org.apache.ant_1.8.2.v20120109-1030\bin;%ANT_HOME%\bin;%GRADLE_HOME%\bin;
ANDROID_HOME D:\Android\sdk

Build_tools必须是19以上
D:\Android\sdk\build-tools //Build_tools文件(android-4.4.2)要放在sdk的build-tools目录中

D:\first_soft\RoBoGuiceTest>gradle build 在dos中进入项目的目录中,执行gradle build就可以了
生成的文件在build\apk中
需要两份AndroidManifest,build.gradle,key.keystore


在虚拟机中安装apk //http://www.apkbus.com/android-123971-1-1.html
1、首先将你要安装的apk放入android-sdk当中platform-tools的目录当中(与adb.exe同目录)
2、window+r输入cmd之后点击确定,找到android-sdk的存放目录(此处已D盘根目录为例); //d: //cd D:\Android\sdk\platform-tools
3、输入adb install weixin.apk则安装成功(前提是模拟器必须打开);(见图3) //名字不要太长


【百度地图sdk】 //API控制台
http://lbsyun.baidu.com/
http://developer.baidu.com/map/
先注册
再创建应用
复制eclipse中preference-->Android-->Build-->SHA1 fingerprint
EF:57:D3:69:01:DA:D0:5D:86:2F:C2:50:0F:67:BB:BA:21:C5:6A:79;com.tarena.tlbs //在eclipse中复制的+包名(就是你Manifest中的包名)
6418840 tlbs baKpSY7NfoacVywMZvjd08lp

eclipse 在64位操作系统时,在eclipse中找不到SHA1 fingerprint
只有通过dos命令行得到
C:\Users\BaseKing-Sunie>cd .android
C:\Users\BaseKing-Sunie\.android>keytool -list -v -keystore debug.keystore //测试的
输入密钥库口令:
密钥库类型: JKS
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: androiddebugkey
创建日期: 2015-7-27
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=Android Debug, O=Android, C=US
发布者: CN=Android Debug, O=Android, C=US
序列号: 2fbb8517
有效期开始日期: Mon Jul 27 11:14:37 CST 2015, 截止日期: Wed Jul 19 11:14:37 CST
2045
证书指纹:
MD5: F8:49:59:BE:70:A3:7C:2B:B4:CC:D0:80:20:6C:34:E1
SHA1: D9:CB:10:64:1B:A2:2D:0D:4C:3A:FB:ED:49:B5:AC:04:0D:0A:3B:28
SHA256: F8:14:26:85:26:ED:63:CF:66:C4:C3:49:9D:05:5F:BA:92:68:FA:B6:B9:
A3:65:41:53:A7:23:E6:5C:5C:30:4A
签名算法名称: SHA256withRSA
版本: 3


【代码混淆后,百度地图】
要加上
-libraryjars libs/baidumapapi_v2_1_3.jar //改成自己用的版本
-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.**{*;}

保持百度地图相关类不被混淆,但是地图仍然出错(只显示网格,无法搜索POI等),这是为什么呢?原因是,混淆前的SHA1和混淆后的SHA1不同,你使用的百度AK依然是混淆前申请的,所以用在混淆后的安装包里当然无法使用了,解决办法就是用混淆时所用的签名文件中的SHA1重新去百度官网申请AK后再重新打包。
C:\Users\BaseKing-Sunie>cd/d E:\人人打车\签名文件 //进入签名文件目录
E:\人人打车\签名文件>keytool -v -list -alias renren -keystore keystore_driver //renren是别名 keystore_driver是签名文件名字
输入密钥库口令: //此处是密码 //正式的
别名: renren
创建日期: 2014-11-7
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=renren, OU=renren
发布者: CN=renren, OU=renren
序列号: 545c9686
有效期开始日期: Fri Nov 07 17:53:10 CST 2014, 截止日期: Sat Oct 25 17:53:10 CST
2064
证书指纹:
MD5: 41:25:25:09:BA:E6:8C:C1:31:25:23:4C:3B:82:A5:E5
SHA1: FE:5E:66:1A:29:1C:57:47:78:9A:80:80:02:34:79:5F:91:53:0B:D3
SHA256: D9:6F:61:87:8D:88:21:DC:6B:E9:5F:28:B4:BD:12:D8:66:A7:43:48:4E:
46:8E:11:05:F7:A6:06:01:9C:ED:45
签名算法名称: SHA1withRSA
版本: 3



【百度语音合成(TTS)SDK使用方法】
http://blog.csdn.net/zpf8861/article/details/32311875
http://yuyin.baidu.com/docs/tts/119
【代码混淆】
http://blog.csdn.net/binyao02123202/article/details/18940715
【百度语音合成】
Proguard 配置
如果应用配置了代码混淆,需要在 Proguard 配置
keep class com.baidu.android.**{*;}
keep class com.baidu.speechsynthesizer.**{*;}


【百度地图使用】
地理编码指的是将地址信息建立空间坐标关系的过程。有可分为正向地图编码和反向地图编码。
在线建议查询是指根据关键词查询在线建议词,实现方式如下:
http://developer.baidu.com/map/sdkandev-4.htm

百度定位locSDK_4.1.jar
百度地图baidumapapi_v2_4_1.jar,
libBaiduMapSDK_v2_4_1.so
百度导航galaxy_mini.jar,
BaiduLBS_Android.jar,
android-support-v4.jar,
android_api_1.1_forsdk.jar,
liblocnaviSDK.so,
libejTTS.so,
libCNPackage.so,
libapp_BaiduNaviApplib_v1_0_0.so

zxing-2.0-core.jar生成二维码图片,解析二维码图片,google的一个开源项目

galaxy_lite.jar是百度 Android公共基础库,如果项目中还集成了其它百度 SDK,如 PushSDK,在打包过程中出现类似如下的错误信息:
[2013-10-22 11:02:57 - Dex Loader] Unableto execute dex: Multiple dex files defineLcom/baidu/android/common/logging/Configuration; [2013-10-22 11:02:57 -VoiceRecognitionDemo] Conversion to Dalvik format failed: Unable to executedex: Multiple dex files define Lcom/baidu/android/common/logging/Configuration;
请将此 Jar 包移除。如果 Eclipse ADT版本插件低于 17,需要手工添加依赖库,添加方法为:Project => Properties => Java Build Path => Libraries => AddJAR... 3


【代码混淆后,百度语音】
-keep class com.baidu.android.**{*;}
-keep class com.baidu.speechsynthesizer.**{*;}
分正式版和测试版两个

 


【代码混淆后,百度导航】
要加上
-keep class com.baidu.navisdk.comapi.tts.** { *; } #【有时候保证不混淆的代码准确到整个包名,也可以确保不混淆。导航初始化】
-keep interface com.baidu.navisdk.comapi.tts.** { *; }
-dontwarn com.baidu.navisdk.comapi.tts.**

-keep class com.sinovoice.**{*;}
-keep interface com.sinovoice.**{*;}
-dontwarn com.sinovoice.**




【libs中的.jar】
二维码图片
zxing-2.0-core.jar生成二维码图片,解析二维码图片,google的一个开源项目。

百度导航
galaxy_mini.jar,
BaiduLBS_Android.jar,
android-support-v4.jar,
android_api_1.1_forsdk.jar,
liblocnaviSDK.so,
libejTTS.so,
libCNPackage.so,
libapp_BaiduNaviApplib_v1_0_0.so

百度定位
locSDK_4.1.jar


【hprof】【检查内存泄露】
导出hprof文件后,
在sdk\tools\hprof-conv.exe hprof文件名 导出hprof文件名

memory analayzer tools
1,运行程序 ddms 生成hprof 文件,
2, 转换 D:\android-sdk-windows\android-sdk-windows\tools\hprof-conv.exe
有的sdk的hprof-conv.exe不在tools中在platforms-tools中

hprof-conv.exe ddms.hprof 0714.hprof
3,解压内存分析工具
3.1 查看java sdk的版本是32位还是64位
3.2 解压\projectRes2005-06-06\技术资料\内存优化
3.3 执行MemoryAnalyzer.exe
3.3.1,openfire 选第一个
3.3.2 左边有个数据库图标 overview




【.9.PNG格式】
我不想在这里过多的讨论PNG格式的定义问题。但是.9.PNG确实是标准的PNG格式,
只是在最外面一圈额外增加1px的边框,这个1px的边框就是用来定义图片中可扩展的和静态不变的区域。
特别说明,left和top边框中交叉部分是可拉伸部分,未选中部分是静态区域部分。right和bottom边框中
交叉部分则是内容部分(变相的相当于定义看一个内边距,神似padding功能,后面我会单独介绍一下),这个参数是可选的


【环信SDK】p2p(不经过服务器)支持实时音视频
注册之后会有一个应用名字,放在values中


【有米】广告
加三行代码


【简历】
很简单啊,在上一家单位的职位上直接写项目经理,项目经验,直接写精通蓝牙,精通音视频解码,我擦,保证你的电话被爆菊
10:39:24
黄少军--18060734772 2015-7-6 10:39:24
电话留刚哥的..
李刚~湖北潜江 2015-7-6 10:39:43
然后服务端,直接写,nginx负载均衡,动静分离,分布式缓存处理。数据库分库,读写分离

 

【环境变量】
ANDROID_SDK_HOME D:\Android\sdk
ANT_HOME D:\Android\eclipse\plugins\org.apache.ant_1.8.2.v20120109-1030;
CLASSPATH .
JAVA_HOME C:\Program Files\Java\jdk1.6.0_10
PATH %WPS_HOME%;%JAVA_HONE%\bin;%PATH%;D:\Android\sdk\platform-tools;D:\Android\eclipse\plugins\org.apache.ant_1.8.2.v20120109-1030\bin;%ANT_HOME%\bin;
TEMP %USERPROFILE%\Local Settings\Temp
TMP %USERPROFILE%\Local Settings\Temp
WPS_HOME C:\Documents and Settings\Administrator\Local Settings\Application Data\Kingsoft\WPS Office\9.1.0.5119\office6


【android-support-v7-appcompat】 //删除Bin 目录下的文件,重新编译
android的res目录是固定的,只能是下面的几种,如果加了其他的目录,它会报‘invalid resource directory name'的错误,
其实加了其它系统不认的目录,系统也不能提供相应的象Resources.getDrawable() and Resources.getColor(), Resources.openRawResource() 去引用资源呀。
anim
drawable
layout
values
raw
color
此外,是不是能采用子目录的方式呢?这样编辑器是可以通过的,不会报错
注:采用子目录的方式可以编译通过,但是通过R无法找到子目录和子目录中的资源


【查看源码】
Android 如何在Eclipse中查看Android API源码 及 support包源码
http://blog.csdn.net/vipzjyno1/article/details/22954775
之后找到你所安装的SDK所在的目录,我的SDK目录路径是:C:\Users\Administrator\android-sdks
找到各个版本的对应sources文件夹
我们拿4.3来做个例子(android-19 就是对应4.3)
找到目录路径
C:\Users\Administrator\android-sdks\sources\android-19
方法1.
直接点击链接,发现无法看源码之后,点击那个按钮,在弹出框中选择第三个,然后输入...\sources\android-19这样的目录,就可以看源码了。
或者
方法2.
之后右击你的项目,选菜单最下方的Properties --- Java Buld Path --- Libraries --- android 4.3 --- android.jar
点击Edit,
在上图所示输入框放入你前面源码的目录,之后项目会自动更新,之后便可以查看源码了。


【源代码导入方式】 //导入源代码
android.support.v4.view.ViewPager
的源代码导入方式

在libs目录下
新建android-support-v4.jar.properties的file文件,并在file文件内写入
src=D:/Android/sdk/extras/android/support/v4/src/java
之后close project,再open project,就可以看见源代码了
(support.v4的源代码是在sdk中的extras中,不像其他的源代码是在sources中)

【Dialog】
mProgressDialog.setCanceledOnTouchOutside(false);// 点击弹窗外的区域是否可取消


ThinkAndroid是包含Android mvc和简易sqlite orm以及ioc模块,它封装了Android httpclitent中的http模块,
具有快速构建文件缓存功能,无需考虑什么格式的文件,都可以非常轻松的实现缓存,它实现了图片缓存,在android中
加载的图片的时候oom的问题和快速滑动的时候图片加载位置错位等问题都可以轻易的解决掉。他还包括了一个手机开发中
经常应用的实用工具类,如日志管理,配置文件管理,android下载器模块,网络切换检测等等工具。
ThinkAndroid的开发宗旨是简洁,快速的进行Android应用程序的开发


【android:maxlength】
android:maxLength="10"
英文+汉字一共10字符,比如“android开发者” 7个字母+3个汉字。再多的部分就不会显示了。
【android:ems="10"】
表示长度为10个单位(具体是多长不清楚),再多的就换行显示
设你输入的参数为n, 屏幕显示的数量为m。
值为1-5时,m = n..
6-11时,m = n+1。
12-18时,m = n+2。
再大我就没测试了,因为屏幕放不下了……………………
基本是符合规律的,对于结果+1和+2,我的猜想是,汉字间是有间隙的,汉字一多,加上间隙,宽度就会增大。也只是猜想,再反过来看看API。
虽然还是不明白ems是什么,但是这里有个很重要的词,wide,宽度范围,而没有强调长度,那么我想应该就是字符在屏幕中所占的宽度了,既然这样,就和屏幕宽度和字体大小有直接的关系。
本文到此基本能结束了,相信大家也有点了解了,虽然我也不能确定自己的猜想是正确的,但是拿来用应该没问题了,但是我对这个方法还有点吐槽:
1, GoogleAPI会以汉字为基准吗?地位一下提高的感觉啊……
2, 对于ems这种英文符号,没有意义,我们该怎么猜测。
3, 在android条件下,各种分辨率,各种屏幕标准,山寨手机还喜欢篡改默认字体的情况下用这种空间布局属性实在不太好适配呀……有较大的局限性
4, 综上所述,这个属性和方法不好用……over。

 

 

 

 

 

 


【ThinkAndroid】主要有以下模块:

MVC模块:实现视图与模型的分离。
ioc模块:android中的ioc模块,完全注解方式就可以进行UI绑定、res中的资源的读取、以及对象的初始化。
数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。
http模块:通过httpclient进行封装http数据请求,支持异步及同步方式加载。
缓存模块:通过简单的配置及设计可以很好的实现缓存,对缓存可以随意的配置
图片缓存模块:imageview加载图片的时候无需考虑图片加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。
配置器模块:可以对简易的实现配对配置的操作,目前配置文件可以支持Preference、Properties对配置进行存取。
日志打印模块:可以较快的轻易的是实现日志打印,支持日志打印的扩展,目前支持对sdcard写入本地打印、以及控制台打印
下载器模块:可以简单的实现多线程下载、后台下载、断点续传、对下载进行控制、如开始、暂停、删除等等。
网络状态检测模块:当网络状态改变时,对其进行检测。


【getSystemService】
getSystemService是Android很重要的一个API,它是Activity的一个方法,根据传入的NAME来取得对应的Object,然后转换成相应的服务对象。以下介绍系统相应的服务。
传入的Name | 返回的对象 | 说明
WINDOW_SERVICE WindowManager 管理打开的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
POWER_SERVICE PowerManger 电源的服务
ALARM_SERVICE AlarmManager 闹钟的服务
NOTIFICATION_SERVICE NotificationManager 状态栏的服务
KEYGUARD_SERVICE KeyguardManager 键盘锁的服务
LOCATION_SERVICE LocationManager 位置的服务,如GPS
SEARCH_SERVICE SearchManager 搜索的服务
VEBRATOR_SERVICE Vebrator 手机震动的服务
CONNECTIVITY_SERVICE Connectivity 网络连接的服务
WIFI_SERVICE WifiManager Wi-Fi服务
TELEPHONY_SERVICE TeleponyManager 电话服务


【更新时间】
Time time = new Time();
time.setToNow();
tvDate.setText(time.format("%Y-%m-%d"));//输出2015-07-29格式
tvTime.setText(time.format("%H:%M"));


【&0xff】//取后八位
System.out.println(257 & 0xff);//输出1

【经纬度】Longitude,latitude
经纬度的整数值为1/10000分,要获得相对应的度,需要除以600000。


【ellipsize】
android:ellipsize=”start”—–省略号显示在开头 "...pedia"
android:ellipsize=”end”——省略号显示在结尾 "encyc..."
android:ellipsize=”middle”—-省略号显示在中间 "en...dia"
android:ellipsize=”marquee”–以横向滚动方式显示(需获得当前焦点时)

 


【异常】
Project has no default.properties file! Edit the project properties to set one.错误解决方案
Project has no project.properties file! Edit the project properties to set one.和上面的解决方法一样

从外面import项目,可能会出现Project has no default.properties file! Edit the project properties to set one.
错误,这是因为default.properties应该是程序自动生成的,但是拷入的项目中存在着default.properties文件,所以就会产生错误。

解决方法:
1 删掉已导入的项目,然后将硬盘上的要拷入的项目中的default.properties文件剪切到别的地方
2 然后将改变后的项目重新拷入,再在导入的项目中新建一个File,名字为default.properties
3 然后用记事本把原来的default.properties打开
4 将里面的内容拷入项目中的default.properties中,然后选中导入的项目,refresh一下即可解决
http://blog.csdn.net/wwdzwjsw4106/article/details/7230888


【shareduserid】
一。
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是可以互相访问任意数据. 同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样。
二.
(1)在AndroidManifest. (2)在Android.mk文件里面添加LOCAL_CERTIFICATE := platform(使用系统签名)
(3)在源码下面进行mm编译
三.
这样生成的apk能够获取system权限,可以在任意system权限目录下面进行目录或者文件的创建,
以及访问其他apk资源等(注意创建的文件(夹)只有创建者(比如system,root除外)拥有可读可写权限-rw-------)。
系统中所有使用android.uid.system作为共享UID的APK,都会首先在manifest节点中增加android:sharedUserId="android.uid.system",然后在Android.mk中增加LOCAL_CERTIFICATE := platform。可以参见Settings等
系统中所有使用android.uid.shared作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.uid.shared",然后在Android.mk中增加LOCAL_CERTIFICATE := shared。可以参见Launcher等
系统中所有使用android.media作为共享UID的APK,都会在manifest节点中增加android:sharedUserId="android.media",然后在Android.mk中增加LOCAL_CERTIFICATE := media。可以参见Gallery等。


【字符串部分上色】
TextView tvQuestion = (TextView) layout.findViewById(R.id.tv_question);
String text1 = "乘客已向您账户支付元";
String text2 = Utils.formatMoney(order.fee);
String text3 = "元";
tvQuestion.setText(Utils.colorString(text1.length(), text1.length()
+ text2.length(), text1 + text2 + text3, getResources()
.getColor(R.color.money_orange)));

public static SpannableStringBuilder colorString(int start, int end,
String str, int color) {
SpannableStringBuilder spannable = new SpannableStringBuilder(str);// 用于可变字符串
ForegroundColorSpan span = new ForegroundColorSpan(color);
spannable.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}

 

【clone()】 //克隆
clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的。一般而言,clone()方法满足以下的描述:
  (1)对任何的对象x,都有:x.clone()!=x。换言之,克隆对象与原对象不是同一个对象。
  (2)对任何的对象x,都有:x.clone().getClass() == x.getClass(),换言之,克隆对象与原对象的类型一样。
  (3)如果对象x的equals()方法定义其恰当的话,那么x.clone().equals(x)应当成立的。
浅克隆字段是值类型的,就好像第一张图,a把name,age都复制到b,c上了(但是b,c都是一个新对象了,外面我画了方框)
如果是引用类型的,就好像第二张图,b,c都直接引用a对象的work对象,而没有重新创建自己的work对象
深克隆如第三张图,b,c都创建了一个work对象,然后a把workName,workAge都复制到b,c上了,

 

【imageView/imageButton】
imageView:src的图片会撑大
imageButton:src的图片不会撑大

android:background="@drawable/down_bg"

【setTextColor】
btnCancel.setTextColor(Color.rgb(102, 102, 102));

【小米2s】
小米2s(MIUI7.0)手机要连接eclipse,必须进入关于手机,多次点击MIUI版本启动开发者模式,
以及在其他高级设置里的开发者选项中开启开发者选项,打开USB调试。



【base64】
java实现图片与base64字符串之间的转换
package com.zxc.testjava.ant;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class TestChangeImage {
public static void main(String[] args) {
String strImg = GetImageStr();
System.out.println(strImg);
GenerateImage(strImg);
}
// 图片转化成base64字符串
public static String GetImageStr() {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
String imgFile = "C:/Users/Star/Desktop/test.png";// 待处理的图片
InputStream in = null;
byte[] data = null;
// 读取图片字节数组
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);// 返回Base64编码过的字节数组字符串
}
// base64字符串转化成图片
public static boolean GenerateImage(String imgStr) { // 对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) // 图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
try {
// Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
// 生成jpeg图片
String imgFilePath = "C:/Users/Star/Desktop/test22.png";// 新生成的图片
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
}