安卓基础及手机安全卫士知识点
1、 录案例保存数据:
a. 要把一个数据写到文件里,首先创建一个File对象;创建一个输出流;
2、安卓中保存文件则存在data/dada/包名/目录/文件名;或Sd卡;
3、主线程中不能联网等的耗时操作,所以联网的代码就要在子线程里去写,
显示UI的代码要写在主线程里;
4、土司也是UI的显示,要在主线程中去执行;
5、我们创建的流管道或返回的流,里面都是数据信息,我们需要时去读或者在写出来;
6、上网时服务器返回的状态码原来都是真的;
7、公共wifi可能会用get请求方式编写一个程序来获你的隐私信息;
安卓里用get请求方法也算是安全的,不像浏览器那样暴露在外面;
8、服务器给你发消息用输出流,客户端请求时要用输入流;
9、(第六天)get请求地址栏是URL+请求内容;
post请求:
(1)post请求的地址栏就是一个路径;(2)post请求必须制定写给服务器数据的长度;(3)post请求
(4)post请求是以流的方式(二进制01001)写数据给服务器的;传数据没有长度的限制;(5)代码写起来比较麻烦
post请求必须制定ContentType类型;
10、下载就是从服务器端去拿东西;
11、在安卓里如果控件标签里面没有子标签的话,直接写一个闭合的就可以了;
12、在类中方法与方法之间是等级的,可以相互调换位置;
13、页面之间的交互很好玩;
14、ListView一般是配合集合来使用的;
15、在安卓里清单文件里的。每一个节点都对应的有一个类;
16、boot开机,启动的意思;
17、Itent是意图对象,开启一个界面意图对象里必须填写上下文对象和要开启界面的类的字节码文件
18、睡一会 sleep必须在子线程去执行;
19、唯有setProgress可以在子线程更新UI,因为它的底层也是发消息机制;
20、这个方法是谁的,这个this就是谁;
21、功能快捷键:ctrl+alt+下键复制一行
22、方法中get开头的就是拿到一些数据;set开头就是设置一些数据;
23、静态类的写法 public static class Student{ };
24、类型强转,向下转型时,才可以用子类的方法;
25、newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
newInstance主要是使用在单例,new是生成对象。
new是关键字,用来生产对象,可以调用类的公开任何构造方法
而newInstance是反射时用的,只能调用无参数的构造方法,
如果想调用有参数的构造方法,可以用
Constructor的newInstance(Object... initargs) 方法
26、安卓中如果类里自动生成的super没有做什么事,可以把它删掉;
27、错误信息是安全方面的问题的,可能是没有加权限;158
28、在window下系统的可执行文件是.exe
29、在安卓中,ctrl+shift+x,选中变大写; +y是变小写
30、MPAndroidChart下载和文档 ;学习资源
--------------------------------------------------------------------
定义String dateFormat = "yy-MM-dd hh-mm-ss";
31、DateFormat.format(dateFormat, date);获取当前时间,date指的是当前时间的毫秒值;
SystemClock.sleep(10000);让线程睡一会,这个方法不需要抛异常
---------------------------------------------------------------------------
32、如果数据在网络之间的传输,会牵扯到编码的操作,如果把内容直接写在数据库或某个地方是没有编码问题的;
33、System.currentTimeMillis();获取当前时间的毫秒值,直接这样写就能获得;
34、自定义的类,只要重写过toString方法,不调用的话,系统自动调用;打印出来的是内容,而不是内存地址;
35、File not find 文件未找到
36、应用在打开时首先运行的、进入界面的是主界面MainActivity,所以进行一些执行指挥的操作我们要放在主界面;
37、MainActivity中的控件变量不能公开必须私有化
38 安卓中, src (源码), res(布局文件), libs (jar包),assets(资产目录)
38、每个控件对应的都是一个类
39、Activity中默认是竖屏 portrait,android:screenOrientation="landscape"; landscape是横屏的意思
40、我们开启别人的界面,则用隐式意图,开启自己自定义的界面则用显示意图
41、这个方法是A开启B界面,并且B界面在关闭的同时返回内容给A界面, 开启B的目的是索要一个结果
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);//第二个参数叫什么无所谓,是个请求碼
42、缩放的比例 分子是图片的大小 分母是屏幕的大小,算一下宽的,比例,再算一下高的比例,然后求比例大的
43、任何一个控件都可以设置点击事件
44 一个有set,get方法的类,它一定有个属性是set后面的
45 bin 二进制,程序的运行的目录
46 增强for是没有下标的,用到下标的循环不能使用它
47 内部类也可以定义成员变量,这个变量属于这个类的,比如匿名内部类
48 private Random random = new Random();也可以这种方式创建对象
49 只有把进程关了应用才退出
50 睡眠的操作只能在子线程中去执行
51 ActivityManager :Activity界面的Log的日志查看器
52 数据库的解析也是IO流的操作,也是耗时的操作;以后ListView再加载数据 数据的获取不管多少 一律放在子线程当中操作
53 dp.dismiss()关闭对话框可以在子线程中更新UI
54 ctrl+k 查找 .ctrl+h安卓工程查找
55 serializable 是存储在文件中、parcelable是存储在内存中的 sp是存的xml配置文件
56 //:直接用Intent传数据
Intent intent = new Intent(MainActivity.this,OtherActivity.class);
intent.putExtra("name", "Nicole");
intent.putExtra("age", 25);
intent.putExtra("address", "Shenzhen");
//:直接用intent获取 intent 中传递的数据
Intent intent = getIntent();
String nameString = intent.getStringExtra("name");
int age = intent.getIntExtra("age",0);
String addressString = intent.getStringExtra("address");
57 android:layout_centerVertical="true" 上下居中
58 控件显示也是在解析xml文件 也是IO流的操作 所以是耗时操作
59 变量一般要加上非null判断.集合非null和它的长度size()都要判断;
60 null与空字符串的区别:
空字符串是"",会创建一个对象,内容是“”,有内存空间。
而null,不会创建对象,没有内存空间。
name==null 是判断name有没有内存空间,
"".equals(name) 是判断name的内存空间中的值是不是空字符串,
没有内存空间的话是不能对变量或对象进行操作的。会出异常。
61 如果是 int 型的数据,那就用 ==;如是 String 型的数据,最好使用 equals,不要用 == 。
62 知识点 选中变量 ctrl+k可以进行查找
63 new出对象了,说明此对象 开辟了内存空间 则不为null
64 不同的布局文件id可以相同
65 在同一个应用中 优先级相同的情况下,代码里的广播先监听到 ,清单注册的在其后;不同应用,先安装的
应用先收到广播
在代码中注册的强制让优先级是Int类型最大值
尽管系统推荐的优先级是-1000~1000 但是也可以写的更大 所以我们写成int类型最大值
这样能够比先安装的应用还先收到广播事件。是安卓的漏洞
66 内容观察者是通过内容解析者来注册的
67 对话框是dismiss掉 控件是GONE掉
68 getRowX:触摸点相对于屏幕的坐标
getX: 触摸点相对于按钮的坐标
getTop: 按钮左上角相对于父view(LinerLayout)的y坐标
getLeft: 按钮左上角相对于父view(LinerLayout)的x坐标
Y轴同理
69 intent.setAction("")设置意图过滤器动作
70 Packamanager pm=getPackamanager() 获取手机上安装的应用信息
ActivityManager am =getSystemService(参数) 一般获取正在运行的应用进程信息
71 布局文件默认字体大小是14sp;
72 进程分五个等级: 前台进程, 可视进程, 服务进程 ,后台进程,空进程;
杀进程只能杀死后台和空进程
73 adapter.notifyDataSetChanged()调用这个方法刷新UI 它会重新调用getView和getCount()方法;
notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来
刷新每个Item的内容,可以实现动态的刷新列表的功能。
74 如果点击事件 设置是按钮 则在点击按钮之后 会弹起来,如果其他的控件则不会
75 任何一个控件 都可以设置点击事件 不仅限于按钮
76 应用的唯一标识 就是包名
77 状态选择器 <!--selector,true表示选择之后 false表示选择之前
-->
(1)state_enabled="false" 表示控件不可用的状态,一般放在第一行
(2)focused="true"有焦点时的状态,focused="false"没有焦点时的状态
(3)pressed 表示按下或没按下之前
78 Fragment不需要在清单文件里配置,它不是四大组件; 在Fragment中 上下文则是getActivity()
Fragmen的生命周期和Activity的几乎是一样的
Fragment有onCreate方法
Fragment有onCreateView方法
Fragment也有onDestroyView()方法
79 数据的固化存储有多种方式 :文件 ,sp,数据库,网络存储,内容提供者;
80 快捷键小知识 : 选中之后 alt+shift+r 改一个或多个字符 ,再回车, 其他的也会跟着改
81 Cursor cursor = database.query(TABLE_NAME, null, null, null, null, null, null);
cursor相当于一个表格 上面有指针 条件满足时可以移动
81 onCreate(参数)可以初始化一些小数据
82 BaseAdapter适配器的getCount()方法 不仅局限于返回(return)个数;需要时,return前面可以写任何代码;
83 线性布局,相对布局等都是装控件的控件,可以装TextView,ImagView等,是继承于ViewGroup; 像TextView,ImagView等是继承于View的;
84 进度条 放在主线程,放在子线程都可以更新
85 allowPackageNames.clear();//清空,全部清空,remove是一个一个的清
86 public void onBackPressed() {//退出键监听
// 当点击返回键时 应该回到桌面 即回到luncher应用
/*系统的意图过滤器
* <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
*
*/
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
intent.addCategory("android.intent.category.MONKEY");
startActivity(intent);
finish();
}
87 getWritableDatabase()和getReadableDatabase()的区别:前者是线程安全,后者是线程非安全的
88 内容观察者不仅局限于数据库 用时协议必须是content://haha/abc;两个斜杠之后叫主机名,abc是携带的数据
String lastPathSegment = uri.getLastPathSegment()可以拿到最后携带的数据即abc
89 在Fragment中注册内容观察者要getActivity().getContentResolver().registerContentObserver(uri, true,
unlockObserver); true 表示模糊感应 只要主机名对 那边通知传过来的数据我们都可以收到
getActivity()指的是获得Activity()界面对象
90 注册内容观察者自定义类private class AppUnlockObserver extends ContentObserver {
public AppUnlockObserver(Handler handler) {
super(handler);
}
@Override//必须重写的方法
public void onChange(boolean selfChange, Uri uri) {
在大括号里可以接收到 那边大吼发出来的通知即uri
String lastPathSegment = uri.getLastPathSegment()可以拿到最后一个斜/后的数据
}
91 内容观察者不仅局限于数据库 我们自己也可以创建一个类 脱离数据库;以后用A通知B你除了
用广播之外也可以用内容观察者;内容观察者是轻量级的不是四大组件;如果你的程序功能不是特别强大,可以用内容观察者;广播不仅可以
监听自己发的广播以外 还可以监听系统发的广播;
92 文件的唯一标识MD5值; 安卓里/表示路径;\表示路径时,必须要写成\\
93 onCreate方法 做一些数据的初始化加载等操作时 代码太多时 尽量做成一个方法 比如找到控件的操作 ,这样看起来 比较干净整洁
94 安卓里的/data/app路径指的是用户的应用 ,/system路径下指的是系统的应用
95 软件里的所有值 几乎是存在sp中的
96 电话打出是广播 打入是telephoneManager
97 进程中 前台进程是杀不死的
98 安卓drawable下可以放状态选择器,帧动画,图片,层级列表layer—list,shape资源,使旋转的
progressBar等,
drawable是res下自己建的文件夹
99 Java编辑器 转至上一个成员 Ctrl+Shift+↑
Java编辑器 转至下一个成员 Ctrl+Shift+↓
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 上一个编辑器 Ctrl+Shift+F6
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 重命名 Alt+Shift+R
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓
全局 打开类型 Ctrl+Shift+T
Ctrl+T也是一个查询类的快捷键
全局 打开类型层次结构 F4
全局 打开声明 F3
文本编辑器 转至行 Ctrl+L
找到下一个引用Ctrl+K
全局 打开搜索对话框 Ctrl+H
全局 全部保存 Ctrl+Shift+S
全局 关闭 Ctrl+F4
全局 全部关闭 Ctrl+Shift+F4
全局 添加/去除断点 Ctrl+Shift+B
Java编辑器 添加导入 Ctrl+Shift+M
win10快捷键 ,ctrl+win+D/f4切换桌面
100 <!-- <SlidingDrawer抽屉的根节点,content抽屉的内容,handle抽屉的把手 -->
android:orientation="horizontal"抽屉的方向
101 android:gravity="bottom"在底部对齐 ,android:gravity="right" 在右侧;
<!--ScrollView 滾動条 --> aidl 回掉 xml
102 btnClear.setEnabled(false);//按钮不可被点击
llCacheInfoList.removeAllViews();//清空容器中的所有view
103 安卓中的view控件像树形一样,任何一个view只有一个父亲,可以有多个孩子
104 比较笨的一种认识:Android中以on开头的方法都是回调方法:onCreate (),onStart (),onPause (),onStop()等等。。
在Activity中定义了很多生命周期的不同状态要调用的方法,这些方法都是空实现,系统框架要调用,用户也要调用来实现。
105 我们是利用了系统的漏洞来清理缓存的 ,申请足够大的空间, 让系统帮我们清理缓存
106 Application 它的这个onCreate方法比所有的Activity的onCreate都先执行,它代表整个应用,做一些数据初始化的操作最好不过,也可以进行对象的传递
还可以进行异常错误信息的捕获
它是全局的,Activity的上面就是Application,如果A界面与B界面之间通信,想传一个对象过去,又不想实现序列化接口,那必须借助Application了;
举例界面之间传递对象:MyApplication app = (MyApplication)getApplication();
app.datas.put("fadsf", new Object());//存入对象
在Activity中都有这个getApplication()方法;
107 上下文知识点:如果是在Activity的成员方法中,可以直接用this代替context。
18638281536 2946372089
论坛FindSpace:各种开发技术论坛
MSDN也是
108 performClick 执行点击事件的意思
109 关于标记false true 开关方面,设置的初始化状态是一种 当你点击触发后 在判断的时候
标记为false 或为true是不确定的; boolean类型默认状态为false
109 如果是一个view 只需要测量自己就可以了,
但如果是一个布局(ViewGrowp),还要测量自己及所有的子view
110 自定义控件 测量大小时,是从父view依次向子view计算的,而获得谁的大小是
不确定的 ,所以有时不止计算一次,计算的值里面 包含大小父view指定的尺寸大小与子view要遵守的模式
111 <ScrollView/>滚动条,加上之后条目才能滚动
112 view里 事件传递时是从外向内一层层传递的,外层父view是先收到事件;而事件的消费是子view先消费,如果子view
不要事件,那么事件一层层再向外传递给父view
自定义控件里:
113 onInterceptTouchEvent(MotionEvent ev){}中断触摸事件的方法:按下,移动,抬起; 返回true是中断事件,返回false不中断
中断之后由onTouchEvent(MotionEvent event){}方法来消费事件
(1)setOnCheckedChangeListener(l)//为单选按钮设置监听事件
(2)setOnItemClickListener(l)//条目监听点击事件
(3)setOnClickListener(this)//监听点击事件, 这个Activity implements OnClickListener
(4)setOnClickListener(l)//监听点击事件; 还有一种是在布局文件中设置OnClick
(5)onTouchEvent(MotionEvent event) {}//触摸点击事件
(6)setOnTouchListener(l)//触摸点击事件
(7)listView.setOnItemLongClickListener(l)//条目长按监听事件
114 public boolean dispatchTouchEvent(MotionEvent ev) {事件的分发方法;
return super.dispatchTouchEvent(ev);
}
事件-- 事件分发--中断--消费; 最后调用onTouchEvent(MotionEvent event){}来消费事件
115 /**
* 如果一个view 即重写了onTouchEvent 方法 ,又设置了 setOnTouchListener
* 那么,setOnTouchListener 中的 onTouch 会执行,而onTouchEvent 方法,就不再执行了
* 前提是都返回的为true; 得出后者优先级高于前者
*/
116 android:layout_margin="50dp"表示外边距
android:padding="50dp"表示内边距
短信管理
1 获得Drawable图片的方法getResources().getDrawable(iconId)
2 state_pressed按下,抬起 状态选择器
3 一个view不一定是一个布局
4 String name=cursor.gerColumnName(i)//获得列的名称
String value=cursor.getString(i)//获得该列的值
int count=cursor.getColumnCount()//获得列的个数
int count =cursor.getCunt()//获得行的个数
cursor和数据库用完一定要关闭;
// 问题 上下文 绝对布局
5 一切条目内容的改变,都要在getView(...)方法和bindView(...)去设置,否则在其他方法中是无效的;
6 所有的监听都会在主线程中执行,所以更新UI的代码也可以在这里写;
7 CursorAdapter比BaseAdapter有非常好用的功能:它可以自动刷新listview和更新数据库;
CursorAdapter的过程:查询数据库--获得Cursor--交给CursorAdapter--由CursorAdapter为listview提供数据--
如果数据库发生变化--由CursorAdapter自动更新数据,自动刷新Listview;
8 ProgressDialog进度条对话框
AlertDialog.uilder对话框
9 Thread.stop();结束线程不能让它直接停止;要让它立刻运行完成
10 数据库查询query(Phone.CONTENT_URI, new String[]{"display_name"}, " data1 = ?", new String[]{address}, null);
//参数一表示Uri;new String[]{"display_name"}表示要查询的列名; data1 = ?表示查询条件;占位符即是new String[]{address},
null表示你要查询的数据是要升序还是降序,不排序则为null;
11 Java中的变量分为局部变量和全局变量,局部变量就是在方法中声明的变量,而全局变量就是在类中声明的变量,在java中有这么一条规则,
声明在方法中的变量在使用时必须要初始化(注意,这里是使用时,如果不使用的话,你也可以不赋值,但是一般变量声明了之后都是要使用的,所以你最好初始化),
局部变量定义的时候不赋值是不会报错, 但是在使用的时候会报错
12 布局属性android:layout_gravity="right"控制自身的对齐方向,让其在父控件的右边
android:gravity="bottom"下方对齐,是控制控件里的内容; 但高度包裹内容和填充满父控件是有区别的
android:layout_gravity="bottom"下方对齐,是控制自己的
android:layout_gravity="right"右方对齐,是控制自己的
android:gravity="top|left"控件内容左上角对齐
注意:layout_是指相对父view的,gravity是指它里面的内容的位置;
13 ListView:
<!-- android:divider="@null" 设置listview分隔线为null,即去掉分割线-->
<!-- android:listSelector="#000000000" 设置listview当前选中的条目的显示效果,透明--->
<!-- android:cacheColorHint="#00000000" 设置listview高光缓冲色,透明-->
<!-- android:scrollbars="none" 设置滚动条样式,none去掉滚动条-->
14 queryHandler.startQuery(88, adapter, uri, projection, " address = ?", new String[]{address}, " date ");
开启异步查询,查询完成后,调用AsyncQueryHandler中的onQueryComplete 方法,
异步查询即是在未来的某个时刻会执行 需要的时候才执行
15 super(cr);调用父类的有参构造方法;
16 PendingIntent sentIntent = PendingIntent.getBroadcast(ctx, 88, intent, PendingIntent.FLAG_ONE_SHOT);
PendingIntent就是对一个 intent和这个intent 要干的事,包装在了一起;
把它的对象扔给别人之后,会获得一个intent对象;根据intent对象判断出你是发广播的,还是开启Activity的;
17 // windowSoftInputMode="adjustResize"重新调整Activity尺寸,比如手机软键盘(清单文件中配置的)
<activity android:name="zz.itcast.smsmangerz18.activity.NewMsgActivity"
android:windowSoftInputMode="adjustResize"></activity>
18 AutoCompleteTextView是重型的组件,它这个类做了大量的工作,能替代PopupWindow,唯一不能做的就是,根据输入框中的内容查询数据获得cursor
<!-- android:completionThreshold="1" 提示框显示之前,用户必须输入的字符的个数,默认是2 -->
<AutoCompleteTextView
android:id="@+id/actv"
android:layout_width="0dp"
android:completionThreshold="1"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="输入号码" />
19 类$类表示内部类,内部接口; _id是联系人号码的唯一标识
20 使用CursorAdapter的条件:ListView的一个条目指向cursor的一条数据,即是listview的所有条目都来自同一个cursor
21 cursor.moveToFirst(); // 移动到第一行,游标默认在第一行的上面
22 刷新listView的方法adapter.notifyDataSetChanged() ;这个方法再次刷新listview之后会复用历史对象,注意listview的优化,getView方法里必须加上else判断;
23
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null){
view = getLayoutInflater().inflate(R.layout.list_item_folder, null);
}else{
view = convertView;
}
tvName.setText(names[position]);//根据条目位置索引设置名称
ivIcon.setBackgroundResource(iconIds[position]);//根据条目位置索引设置图片
//设置显示的短信的个数
tvCount.setText(""+counts[position]);//括号内是int类型的,如果不转换成字符串,系统会认为你是id,会去找的,而我们就是让它显示成数字的,所以要转成字符串
if(position % 2 !=0){// 设置背景
view.setBackgroundColor(Color.GRAY);
}else{//只要上面if else 做了一些listview的复用历史对象的优化;我们下面再if的时候,必须加上else判断,这是规定,否则刷新listview的时候会再次复用对象,页面就会出现问题
view.setBackgroundColor(Color.WHITE);
}
return view; // 如果返回null 会报空指针,而且 ,异常中只有系统代码,没有我们的代码
}
}
24 ListView中,关于逻辑处理的,尽量不要在getView()方法里面去执行;getView()里面尽量只做一些页面显示的处理
25 ContentValues类和Hashtable比较类似,它也是负责存储一些名值对,但是它存储的键值对当中的键是一个String类型,而值都是基本类型,
用于操作数据库,我们将要插入列名和对应的列值放置到一个ContentValues的实例当中
26 CursorAdapter中程序执行顺序: listView.setAdapter(adapter)--设置好之后--展示listview数据--执行--newView方法--bindView--方法
newView方法的返回值view就是bindView方法中的参数一
27 额外知识:
把java代码写在网页里就是jsp;
service是处理业务的——至—把javabean的数据取出来—至—dao数据访问对象,与数据库打交道的
包名:itcast 项目名 ,模块名、dao(接口)
user就是封装类的那个类
每个请求都对应一个servlet;
hint一点就会消失 text则不会有这功能
28 Imageview,ImageButton才有src 属性,其他没有的可以用background;
https://wangdh-PC/svn/MediaPlayer18/
stu/stu
手机影音
1 ----AS错误排除,想知道别人的和自己的为什么错误,自己可以建一个项目,对比一下--
//下面的节点数量和名称套包一致
// project build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
//2.1.3你的斯丢丢版本号 要和导入项目保持一致
classpath 'com.android.tools.build:gradle:2.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
===============================================================
//APP build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 24 //sdk版本号,1.8支持24
buildToolsVersion "24.0.2" //buildTools里面的版本号
defaultConfig {
applicationId "cast.it.mediaplayer188"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
//v7包版本看你的是支持多少,从project structure--app--dependencies可以看到
compile 'com.android.support:appcompat-v7:24.0.0-beta1'
compile 'com.google.android.gms:play-services-appindexing:8.1.0'
}
问题,更新代码
创建类 重写tostring
2 什么时候用序列化:
对象的序列化最大的目的就是进行数据传输,
序列化就是将内存中的类或者对象(你写的类都是存储在内存中的)
变成可以存储到存储媒介中的流,你将类序列化成流之后可以通过互联网传输给别人,你也可以反序列化将别人的序列化流转换成内存中的对象,就这么简单;
a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
3 通过VideoView播放视频的步骤:
a)在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件
b)调用VideoView的如下两个方法来加载指定的视频
setVidePath(String path):加载path文件代表的视频
setVideoURI(Uri uri):加载uri所对应的视频
c)调用VideoView的start()、stop()、psuse()方法来控制视频的播放
VideoView通过与MediaController类结合使用,开发者可以不用自己控制播放与暂停
4 组件之间的传输数据都是通过intent
5
6 程序调用顺序 从上往下,主线程一派,子线程一派;谁需要谁调用,每个方法里面都是至上而下的
7 Fragment类的onCreateView通過返回view來關聯布局
8 Arraylist实现了序列化 Serializable ,而List则没有实现序列化Serializable
9 ViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样,那如何使用它呢,与ListView类似,我们也需要一个适配器,他就是PagerAdapter。ViewPager和Fragment配合使用,在滑动的时候去切换Fragment
从最简单的引导页导航,到轮转广告,到页面菜单等等,无不出现ViewPager的身影。应用广泛,简单好用,更好的交互性
适配器这个东东想必大家都不莫生,在ListView中也有适配器,listView通过重写GetView()函数来获取当前要加载的Item。而PageAdapter不太相同,毕竟PageAdapter是单个VIew的合集。
PageAdapter 必须重写的四个函数
boolean isViewFromObject(View arg0, Object arg1)
int getCount() //返回要滑动的VIew的个数
void destroyItem(ViewGroup container, int position,Object object)//从当前container中删除指定位置(position)的View;
Object instantiateItem(ViewGroup container, int position)//做了两件事,第一:将当前视图添加到container中,第二:返回当前View
10 ScrollView滚动视图是指当拥有很多内容,屏幕显示不完时,需要通过滚动条来显示的视图,
纵向滚动
<ScrollView>
<LinearLayout ........>
<TextView ...../>
<TextView ...../>
<TextView ...../>
<TextView ...../>
</LineraLayout>
</ScrollView>
横向滚动
<HorizontalScrollView >
<LinearLayout ........>
<TextView ...../>
<TextView ...../>
<TextView ...../>
<TextView ...../>
</LineraLayout>
</HorizontalScrollView >
11 XML序列化:写到文件里即是生成一个文件,称为XML序列化,从文件读取数据到内存里是解析XML
12 安卓设计模式:
(1) Application 单例模式
(2) 观察者模式 各种listener
(3) MVC 这个好理解
(4) 响应链 触摸、按键等各种事件的传递
(5) 工厂模式
(6) 适配器模式、策略模式、模板方法模式等。。。。
13 移动动画 ViewPropertyAnimator.animate(video_player_ll_top).translationY(-topLLHeight);
14 其实配了意图过滤器之后,别人则可以通过隐式意图去开启你的界面了;
15 像素 随着放大,是不变的 ;米的话是会变化的
16 Viewgrow,View 一个是容器,一个是控件;
17 drwable的子类 动画(Animation) shape等
18 Handler是线程间的通信,是子线程通知主线程更新UI
19 获得消息对象:
(1) Message msg = Message.obtain();//常用的
(2) Message msg = new Message();(不建议)因为它每次都要创建对象
(3) Message msg = handler.obtainMessage();
msg.obj = "Android群英传:神兵利器";//消息内容
msg.what = 0;消息类型
20 Handler的发消息机制:
handler.sendMessage(msg)发消息--由MessageQueue(消息队列)存储消息
--Looper(轮询器)通过loop()方法不断从消息队列中取消息来进行轮询的,也是循环获取消息,并且是死循环,来查找是否有新消息--如果有消息,就分发
给对应的handleMessage(Message msg);当消息队列中没有消息时,Looper会在那等着,会休眠,等有消息了,再去取消息;
注意:Handler,Message是有多个对象的,MessageQueue,Looper只有一个对象
里面有个消息池,消息池是通过next来连接的
Looper负责获取消息和分发回传消息
21
(1) Message 创建
Message msg = Message.obtain();
msg = new Message();(不建议)
msg = handler.obtainMessage();
handler 创建msg:
public final Message obtainMessage()
{
return Message.obtain(this);
}
this 是 Handler对象
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
message的对象的target属性 = handler对象. ***
obtain()方法分析 -- 看图. ****
(2) Handler创建
直接 new handler();
public Handler() {
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
}
new handler的时候 ,给内部的looper和MessageQueue赋值.
mLooper = Looper.myLooper();
通过 ActivityThread主线程创建的时候,创建的.
main():
Looper.prepareMainLooper();
**--looper.prepare() -- sThreadLocal.set(new looper());//创建了looper
new Looper();
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
***messageQueue的创建是随着looper的创建而创建的.
(3) looper如何醒来
handler.sendMessage()的时候,给looper发送消息,告诉looper该醒来.
发消息是在子线程中 -- looper在主线程. (线程间通信)
Linux PIPE管道
(4)looper取出msg之后,如何发给对应的handler对象
msg.sendToTarget();//发送给msg目标
msg 就是 对应的Handler对象
loop()如何分发消息:
msg.target.dispatchMessage(msg);
handler.dispatchMessage(msg)
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
22 Toast只能在主UI线程使用,使用下面的办法可以解决:
第一种,使用Looper,不过这种办法会终止,子线程之后的代码
//需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,
从消息队列里取消息,处理消息。
Looper.prepare();
Toast.makeText(aActivity.this,"test",Toast.LENGTH_SHORT).show();
Looper.loop();
第二种,就是用 Handler Message
private final Handler msgHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.arg1) {
case R.string.msg_not_network:
Toast.makeText(getApplicationContext(), getResources().getString(R.string.msg_not_network), Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
23.Activity的生命周期,当点击HOme键的时候,会调用onPause()--onStop()不会调用onDestroy() ;
24 Android中GridView控件:
如果是列表(单列多行形式)的使用ListView,如果是多行多列网状形式的优先使用GridView
GirdView的一些属性:
android:numColumns="auto_fit" --------列数设置为自动
android:columnWidth="90dp",----------每列的宽度,也就是Item的宽度
android:stretchMode="columnWidth"------缩放与列宽大小同步
android:verticalSpacing="10dp"----------垂直边距
android:horizontalSpacing="10dp"-------水平边距
1、准备数据源
2、新建适配器
3、加载适配器
GridView(网格视图)是按照行列的方式来显示内容的,一般用于显示图片,图片等内容,比如实现九宫格图,用GridView是首选,也是最简单的
25 四大组件中 允许自己new出来的创建的只有广播,其他的都必须让系统创建,系统是通过反射进行创建的
如果自己new 只是一个普通的java类,则不具备上下文的能力 ;上下文的能力是系统赋予组件的
26 如果是一个接口,我们可以new出这个接口,运用匿名内部类,来实现接口的方法
27 利用绑定方式开启服务的目的,是为了方便调用服务里的方法
28 创建的接口的修饰符和接口里的方法的修饰符都必须是公有的
29 你只可以继承一个类,但你可以实现多个接口,接口相当于干爹
30 权重是线性布局的特性,相对布局的话会控件默认都在左上角
31 绑定开启服务和start开启服务两者混合开启,不仅能调用服务里的方法,还能让服务长期在后台运行;步骤为:
start开启服务--绑定服务---解绑服务
32 利用绑定服务调用服务里的方法
---------------------------------------------------------------------------------------
package zz.itcast.bindservice;
import zz.itcast.whybindservice.R;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
public class MainActivity extends Activity {
private MyServiceConn conn;
// private MyBinder2 binder;
private IService binder2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service = new Intent(this, BindService.class);
conn = new MyServiceConn();
// 这里第一次生效
bindService(service, conn, BIND_AUTO_CREATE);
}
public void callMethodInService(View view){
// BindService bs = new BindService();
//
// bs.showToast();
// 四大组件中 允许我们自己new出来创建的只有广播 其他都必须让系统创建
// 如果自己new 就是一个普通的java类 就不具备上下文的能力了 是系统赋予组件上下文的能力
binder2.callShowToast();
}
private class MyServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
// binder = (MyBinder)service;
// (MyBinder)service 先将Ibinder--- MyBInder 向下转型
// 再将MyBInder 强转成IService 向上转型 由孙子强转成干爹
// 这里面其实做了两次类型转换
binder2 = (IService)service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
----------------------------------------------------------------------------------------
package zz.itcast.bindservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class BindService extends Service {
// 只要这个onBind方法返回不为null onServiceConnected马上就执行 并且系统将这个Ibinder对象传递过去
@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return new MyBinder3();
}
public class MyBinder3 extends Binder implements IService{
@Override
public void callShowToast() {
// TODO Auto-generated method stub
showToast();
}
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("onUnbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println("onCreate");
}
public void showToast(){
Toast toast = Toast.makeText(this, "我是服务里的吐司 你来弹我啊", 0);
toast.show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
System.out.println("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.out.println("onDestroy");
}
}
------------------------------------------------------------------------------------
package zz.itcast.bindservice;
public interface IService {
void callShowToast();
}
33 利用混合开启服务方式,不仅能调用服务里的方法还能,让服务长期在后台运行(音乐盒)
先start开启服务--绑定服务---解绑服务
-----------------------------------------------------------------------------
package zz.itcast.music;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MusicService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
}
private class MyBinder extends Binder implements IPlayer{
@Override
public void callPlay() {
// TODO Auto-generated method stub
playMusic();
}
@Override
public void callPause() {
// TODO Auto-generated method stub
pauseMusic();
}
@Override
public void callRePlay() {
// TODO Auto-generated method stub
rePlayMusic();
}
@Override
public void callStop() {
// TODO Auto-generated method stub
stopMusic();
}
}
public void playMusic() {
System.out.println("播放音乐");
}
public void pauseMusic() {
System.out.println("暂停音乐");
}
public void rePlayMusic() {
System.out.println("续播音乐");
}
public void stopMusic() {
System.out.println("停止音乐");
}
}
--------------------------------------------------------------------------------------
package zz.itcast.music;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
private IPlayer player;
private MyServiceConn conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 先start 再Bind
Intent service = new Intent(this, MusicService.class);
startService(service);
conn = new MyServiceConn();
bindService(service, conn, BIND_AUTO_CREATE);
}
public void play(View view) {
player.callPlay();
}
public void pause(View view) {
player.callPause();
}
public void replay(View view) {
player.callRePlay();
}
public void stop(View view) {
player.callStop();
}
private class MyServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
player = (IPlayer) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
-----------------------------------------------------------------------
package zz.itcast.music;
public interface IPlayer {
void callPlay();
void callPause();
void callRePlay();
void callStop();
}
1、 录案例保存数据:
a. 要把一个数据写到文件里,首先创建一个File对象;创建一个输出流;
2、安卓中保存文件则存在data/dada/包名/目录/文件名;或Sd卡;
3、主线程中不能联网等的耗时操作,所以联网的代码就要在子线程里去写,
显示UI的代码要写在主线程里;
4、土司也是UI的显示,要在主线程中去执行;
5、我们创建的流管道或返回的流,里面都是数据信息,我们需要时去读或者在写出来;
6、上网时服务器返回的状态码原来都是真的;
7、公共wifi可能会用get请求方式编写一个程序来获你的隐私信息;
安卓里用get请求方法也算是安全的,不像浏览器那样暴露在外面;
8、服务器给你发消息用输出流,客户端请求时要用输入流;
9、(第六天)get请求地址栏是URL+请求内容;
post请求:
(1)post请求的地址栏就是一个路径;(2)post请求必须制定写给服务器数据的长度;(3)post请求
(4)post请求是以流的方式(二进制01001)写数据给服务器的;传数据没有长度的限制;(5)代码写起来比较麻烦
post请求必须制定ContentType类型;
10、下载就是从服务器端去拿东西;
11、在安卓里如果控件标签里面没有子标签的话,直接写一个闭合的就可以了;
12、在类中方法与方法之间是等级的,可以相互调换位置;
13、页面之间的交互很好玩;
14、ListView一般是配合集合来使用的;
15、在安卓里清单文件里的。每一个节点都对应的有一个类;
16、boot开机,启动的意思;
17、Itent是意图对象,开启一个界面意图对象里必须填写上下文对象和要开启界面的类的字节码文件
18、睡一会 sleep必须在子线程去执行;
19、唯有setProgress可以在子线程更新UI,因为它的底层也是发消息机制;
20、这个方法是谁的,这个this就是谁;
21、功能快捷键:ctrl+alt+下键复制一行
22、方法中get开头的就是拿到一些数据;set开头就是设置一些数据;
23、静态类的写法 public static class Student{ };
24、类型强转,向下转型时,才可以用子类的方法;
25、newInstance: 弱类型。低效率。只能调用无参构造。
new: 强类型。相对高效。能调用任何public构造。
newInstance主要是使用在单例,new是生成对象。
new是关键字,用来生产对象,可以调用类的公开任何构造方法
而newInstance是反射时用的,只能调用无参数的构造方法,
如果想调用有参数的构造方法,可以用
Constructor的newInstance(Object... initargs) 方法
26、安卓中如果类里自动生成的super没有做什么事,可以把它删掉;
27、错误信息是安全方面的问题的,可能是没有加权限;158
28、在window下系统的可执行文件是.exe
29、在安卓中,ctrl+shift+x,选中变大写; +y是变小写
30、MPAndroidChart下载和文档 ;学习资源
--------------------------------------------------------------------
定义String dateFormat = "yy-MM-dd hh-mm-ss";
31、DateFormat.format(dateFormat, date);获取当前时间,date指的是当前时间的毫秒值;
SystemClock.sleep(10000);让线程睡一会,这个方法不需要抛异常
---------------------------------------------------------------------------
32、如果数据在网络之间的传输,会牵扯到编码的操作,如果把内容直接写在数据库或某个地方是没有编码问题的;
33、System.currentTimeMillis();获取当前时间的毫秒值,直接这样写就能获得;
34、自定义的类,只要重写过toString方法,不调用的话,系统自动调用;打印出来的是内容,而不是内存地址;
35、File not find 文件未找到
36、应用在打开时首先运行的、进入界面的是主界面MainActivity,所以进行一些执行指挥的操作我们要放在主界面;
37、MainActivity中的控件变量不能公开必须私有化
38 安卓中, src (源码), res(布局文件), libs (jar包),assets(资产目录)
38、每个控件对应的都是一个类
39、Activity中默认是竖屏 portrait,android:screenOrientation="landscape"; landscape是横屏的意思
40、我们开启别人的界面,则用隐式意图,开启自己自定义的界面则用显示意图
41、这个方法是A开启B界面,并且B界面在关闭的同时返回内容给A界面, 开启B的目的是索要一个结果
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);//第二个参数叫什么无所谓,是个请求碼
42、缩放的比例 分子是图片的大小 分母是屏幕的大小,算一下宽的,比例,再算一下高的比例,然后求比例大的
43、任何一个控件都可以设置点击事件
44 一个有set,get方法的类,它一定有个属性是set后面的
45 bin 二进制,程序的运行的目录
46 增强for是没有下标的,用到下标的循环不能使用它
47 内部类也可以定义成员变量,这个变量属于这个类的,比如匿名内部类
48 private Random random = new Random();也可以这种方式创建对象
49 只有把进程关了应用才退出
50 睡眠的操作只能在子线程中去执行
51 ActivityManager :Activity界面的Log的日志查看器
52 数据库的解析也是IO流的操作,也是耗时的操作;以后ListView再加载数据 数据的获取不管多少 一律放在子线程当中操作
53 dp.dismiss()关闭对话框可以在子线程中更新UI
54 ctrl+k 查找 .ctrl+h安卓工程查找
55 serializable 是存储在文件中、parcelable是存储在内存中的 sp是存的xml配置文件
56 //:直接用Intent传数据
Intent intent = new Intent(MainActivity.this,OtherActivity.class);
intent.putExtra("name", "Nicole");
intent.putExtra("age", 25);
intent.putExtra("address", "Shenzhen");
//:直接用intent获取 intent 中传递的数据
Intent intent = getIntent();
String nameString = intent.getStringExtra("name");
int age = intent.getIntExtra("age",0);
String addressString = intent.getStringExtra("address");
57 android:layout_centerVertical="true" 上下居中
58 控件显示也是在解析xml文件 也是IO流的操作 所以是耗时操作
59 变量一般要加上非null判断.集合非null和它的长度size()都要判断;
60 null与空字符串的区别:
空字符串是"",会创建一个对象,内容是“”,有内存空间。
而null,不会创建对象,没有内存空间。
name==null 是判断name有没有内存空间,
"".equals(name) 是判断name的内存空间中的值是不是空字符串,
没有内存空间的话是不能对变量或对象进行操作的。会出异常。
61 如果是 int 型的数据,那就用 ==;如是 String 型的数据,最好使用 equals,不要用 == 。
62 知识点 选中变量 ctrl+k可以进行查找
63 new出对象了,说明此对象 开辟了内存空间 则不为null
64 不同的布局文件id可以相同
65 在同一个应用中 优先级相同的情况下,代码里的广播先监听到 ,清单注册的在其后;不同应用,先安装的
应用先收到广播
在代码中注册的强制让优先级是Int类型最大值
尽管系统推荐的优先级是-1000~1000 但是也可以写的更大 所以我们写成int类型最大值
这样能够比先安装的应用还先收到广播事件。是安卓的漏洞
66 内容观察者是通过内容解析者来注册的
67 对话框是dismiss掉 控件是GONE掉
68 getRowX:触摸点相对于屏幕的坐标
getX: 触摸点相对于按钮的坐标
getTop: 按钮左上角相对于父view(LinerLayout)的y坐标
getLeft: 按钮左上角相对于父view(LinerLayout)的x坐标
Y轴同理
69 intent.setAction("")设置意图过滤器动作
70 Packamanager pm=getPackamanager() 获取手机上安装的应用信息
ActivityManager am =getSystemService(参数) 一般获取正在运行的应用进程信息
71 布局文件默认字体大小是14sp;
72 进程分五个等级: 前台进程, 可视进程, 服务进程 ,后台进程,空进程;
杀进程只能杀死后台和空进程
73 adapter.notifyDataSetChanged()调用这个方法刷新UI 它会重新调用getView和getCount()方法;
notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来
刷新每个Item的内容,可以实现动态的刷新列表的功能。
74 如果点击事件 设置是按钮 则在点击按钮之后 会弹起来,如果其他的控件则不会
75 任何一个控件 都可以设置点击事件 不仅限于按钮
76 应用的唯一标识 就是包名
77 状态选择器 <!--selector,true表示选择之后 false表示选择之前
-->
(1)state_enabled="false" 表示控件不可用的状态,一般放在第一行
(2)focused="true"有焦点时的状态,focused="false"没有焦点时的状态
(3)pressed 表示按下或没按下之前
78 Fragment不需要在清单文件里配置,它不是四大组件; 在Fragment中 上下文则是getActivity()
Fragmen的生命周期和Activity的几乎是一样的
Fragment有onCreate方法
Fragment有onCreateView方法
Fragment也有onDestroyView()方法
79 数据的固化存储有多种方式 :文件 ,sp,数据库,网络存储,内容提供者;
80 快捷键小知识 : 选中之后 alt+shift+r 改一个或多个字符 ,再回车, 其他的也会跟着改
81 Cursor cursor = database.query(TABLE_NAME, null, null, null, null, null, null);
cursor相当于一个表格 上面有指针 条件满足时可以移动
81 onCreate(参数)可以初始化一些小数据
82 BaseAdapter适配器的getCount()方法 不仅局限于返回(return)个数;需要时,return前面可以写任何代码;
83 线性布局,相对布局等都是装控件的控件,可以装TextView,ImagView等,是继承于ViewGroup; 像TextView,ImagView等是继承于View的;
84 进度条 放在主线程,放在子线程都可以更新
85 allowPackageNames.clear();//清空,全部清空,remove是一个一个的清
86 public void onBackPressed() {//退出键监听
// 当点击返回键时 应该回到桌面 即回到luncher应用
/*系统的意图过滤器
* <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
*
*/
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
intent.addCategory("android.intent.category.MONKEY");
startActivity(intent);
finish();
}
87 getWritableDatabase()和getReadableDatabase()的区别:前者是线程安全,后者是线程非安全的
88 内容观察者不仅局限于数据库 用时协议必须是content://haha/abc;两个斜杠之后叫主机名,abc是携带的数据
String lastPathSegment = uri.getLastPathSegment()可以拿到最后携带的数据即abc
89 在Fragment中注册内容观察者要getActivity().getContentResolver().registerContentObserver(uri, true,
unlockObserver); true 表示模糊感应 只要主机名对 那边通知传过来的数据我们都可以收到
getActivity()指的是获得Activity()界面对象
90 注册内容观察者自定义类private class AppUnlockObserver extends ContentObserver {
public AppUnlockObserver(Handler handler) {
super(handler);
}
@Override//必须重写的方法
public void onChange(boolean selfChange, Uri uri) {
在大括号里可以接收到 那边大吼发出来的通知即uri
String lastPathSegment = uri.getLastPathSegment()可以拿到最后一个斜/后的数据
}
91 内容观察者不仅局限于数据库 我们自己也可以创建一个类 脱离数据库;以后用A通知B你除了
用广播之外也可以用内容观察者;内容观察者是轻量级的不是四大组件;如果你的程序功能不是特别强大,可以用内容观察者;广播不仅可以
监听自己发的广播以外 还可以监听系统发的广播;
92 文件的唯一标识MD5值; 安卓里/表示路径;\表示路径时,必须要写成\\
93 onCreate方法 做一些数据的初始化加载等操作时 代码太多时 尽量做成一个方法 比如找到控件的操作 ,这样看起来 比较干净整洁
94 安卓里的/data/app路径指的是用户的应用 ,/system路径下指的是系统的应用
95 软件里的所有值 几乎是存在sp中的
96 电话打出是广播 打入是telephoneManager
97 进程中 前台进程是杀不死的
98 安卓drawable下可以放状态选择器,帧动画,图片,层级列表layer—list,shape资源,使旋转的
progressBar等,
drawable是res下自己建的文件夹
99 Java编辑器 转至上一个成员 Ctrl+Shift+↑
Java编辑器 转至下一个成员 Ctrl+Shift+↓
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 上一个编辑器 Ctrl+Shift+F6
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 重命名 Alt+Shift+R
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓
全局 打开类型 Ctrl+Shift+T
Ctrl+T也是一个查询类的快捷键
全局 打开类型层次结构 F4
全局 打开声明 F3
文本编辑器 转至行 Ctrl+L
找到下一个引用Ctrl+K
全局 打开搜索对话框 Ctrl+H
全局 全部保存 Ctrl+Shift+S
全局 关闭 Ctrl+F4
全局 全部关闭 Ctrl+Shift+F4
全局 添加/去除断点 Ctrl+Shift+B
Java编辑器 添加导入 Ctrl+Shift+M
win10快捷键 ,ctrl+win+D/f4切换桌面
100 <!-- <SlidingDrawer抽屉的根节点,content抽屉的内容,handle抽屉的把手 -->
android:orientation="horizontal"抽屉的方向
101 android:gravity="bottom"在底部对齐 ,android:gravity="right" 在右侧;
<!--ScrollView 滾動条 --> aidl 回掉 xml
102 btnClear.setEnabled(false);//按钮不可被点击
llCacheInfoList.removeAllViews();//清空容器中的所有view
103 安卓中的view控件像树形一样,任何一个view只有一个父亲,可以有多个孩子
104 比较笨的一种认识:Android中以on开头的方法都是回调方法:onCreate (),onStart (),onPause (),onStop()等等。。
在Activity中定义了很多生命周期的不同状态要调用的方法,这些方法都是空实现,系统框架要调用,用户也要调用来实现。
105 我们是利用了系统的漏洞来清理缓存的 ,申请足够大的空间, 让系统帮我们清理缓存
106 Application 它的这个onCreate方法比所有的Activity的onCreate都先执行,它代表整个应用,做一些数据初始化的操作最好不过,也可以进行对象的传递
还可以进行异常错误信息的捕获
它是全局的,Activity的上面就是Application,如果A界面与B界面之间通信,想传一个对象过去,又不想实现序列化接口,那必须借助Application了;
举例界面之间传递对象:MyApplication app = (MyApplication)getApplication();
app.datas.put("fadsf", new Object());//存入对象
在Activity中都有这个getApplication()方法;
107 上下文知识点:如果是在Activity的成员方法中,可以直接用this代替context。
18638281536 2946372089
论坛FindSpace:各种开发技术论坛
MSDN也是
108 performClick 执行点击事件的意思
109 关于标记false true 开关方面,设置的初始化状态是一种 当你点击触发后 在判断的时候
标记为false 或为true是不确定的; boolean类型默认状态为false
109 如果是一个view 只需要测量自己就可以了,
但如果是一个布局(ViewGrowp),还要测量自己及所有的子view
110 自定义控件 测量大小时,是从父view依次向子view计算的,而获得谁的大小是
不确定的 ,所以有时不止计算一次,计算的值里面 包含大小父view指定的尺寸大小与子view要遵守的模式
111 <ScrollView/>滚动条,加上之后条目才能滚动
112 view里 事件传递时是从外向内一层层传递的,外层父view是先收到事件;而事件的消费是子view先消费,如果子view
不要事件,那么事件一层层再向外传递给父view
自定义控件里:
113 onInterceptTouchEvent(MotionEvent ev){}中断触摸事件的方法:按下,移动,抬起; 返回true是中断事件,返回false不中断
中断之后由onTouchEvent(MotionEvent event){}方法来消费事件
(1)setOnCheckedChangeListener(l)//为单选按钮设置监听事件
(2)setOnItemClickListener(l)//条目监听点击事件
(3)setOnClickListener(this)//监听点击事件, 这个Activity implements OnClickListener
(4)setOnClickListener(l)//监听点击事件; 还有一种是在布局文件中设置OnClick
(5)onTouchEvent(MotionEvent event) {}//触摸点击事件
(6)setOnTouchListener(l)//触摸点击事件
(7)listView.setOnItemLongClickListener(l)//条目长按监听事件
114 public boolean dispatchTouchEvent(MotionEvent ev) {事件的分发方法;
return super.dispatchTouchEvent(ev);
}
事件-- 事件分发--中断--消费; 最后调用onTouchEvent(MotionEvent event){}来消费事件
115 /**
* 如果一个view 即重写了onTouchEvent 方法 ,又设置了 setOnTouchListener
* 那么,setOnTouchListener 中的 onTouch 会执行,而onTouchEvent 方法,就不再执行了
* 前提是都返回的为true; 得出后者优先级高于前者
*/
116 android:layout_margin="50dp"表示外边距
android:padding="50dp"表示内边距
短信管理
1 获得Drawable图片的方法getResources().getDrawable(iconId)
2 state_pressed按下,抬起 状态选择器
3 一个view不一定是一个布局
4 String name=cursor.gerColumnName(i)//获得列的名称
String value=cursor.getString(i)//获得该列的值
int count=cursor.getColumnCount()//获得列的个数
int count =cursor.getCunt()//获得行的个数
cursor和数据库用完一定要关闭;
// 问题 上下文 绝对布局
5 一切条目内容的改变,都要在getView(...)方法和bindView(...)去设置,否则在其他方法中是无效的;
6 所有的监听都会在主线程中执行,所以更新UI的代码也可以在这里写;
7 CursorAdapter比BaseAdapter有非常好用的功能:它可以自动刷新listview和更新数据库;
CursorAdapter的过程:查询数据库--获得Cursor--交给CursorAdapter--由CursorAdapter为listview提供数据--
如果数据库发生变化--由CursorAdapter自动更新数据,自动刷新Listview;
8 ProgressDialog进度条对话框
AlertDialog.uilder对话框
9 Thread.stop();结束线程不能让它直接停止;要让它立刻运行完成
10 数据库查询query(Phone.CONTENT_URI, new String[]{"display_name"}, " data1 = ?", new String[]{address}, null);
//参数一表示Uri;new String[]{"display_name"}表示要查询的列名; data1 = ?表示查询条件;占位符即是new String[]{address},
null表示你要查询的数据是要升序还是降序,不排序则为null;
11 Java中的变量分为局部变量和全局变量,局部变量就是在方法中声明的变量,而全局变量就是在类中声明的变量,在java中有这么一条规则,
声明在方法中的变量在使用时必须要初始化(注意,这里是使用时,如果不使用的话,你也可以不赋值,但是一般变量声明了之后都是要使用的,所以你最好初始化),
局部变量定义的时候不赋值是不会报错, 但是在使用的时候会报错
12 布局属性android:layout_gravity="right"控制自身的对齐方向,让其在父控件的右边
android:gravity="bottom"下方对齐,是控制控件里的内容; 但高度包裹内容和填充满父控件是有区别的
android:layout_gravity="bottom"下方对齐,是控制自己的
android:layout_gravity="right"右方对齐,是控制自己的
android:gravity="top|left"控件内容左上角对齐
注意:layout_是指相对父view的,gravity是指它里面的内容的位置;
13 ListView:
<!-- android:divider="@null" 设置listview分隔线为null,即去掉分割线-->
<!-- android:listSelector="#000000000" 设置listview当前选中的条目的显示效果,透明--->
<!-- android:cacheColorHint="#00000000" 设置listview高光缓冲色,透明-->
<!-- android:scrollbars="none" 设置滚动条样式,none去掉滚动条-->
14 queryHandler.startQuery(88, adapter, uri, projection, " address = ?", new String[]{address}, " date ");
开启异步查询,查询完成后,调用AsyncQueryHandler中的onQueryComplete 方法,
异步查询即是在未来的某个时刻会执行 需要的时候才执行
15 super(cr);调用父类的有参构造方法;
16 PendingIntent sentIntent = PendingIntent.getBroadcast(ctx, 88, intent, PendingIntent.FLAG_ONE_SHOT);
PendingIntent就是对一个 intent和这个intent 要干的事,包装在了一起;
把它的对象扔给别人之后,会获得一个intent对象;根据intent对象判断出你是发广播的,还是开启Activity的;
17 // windowSoftInputMode="adjustResize"重新调整Activity尺寸,比如手机软键盘(清单文件中配置的)
<activity android:name="zz.itcast.smsmangerz18.activity.NewMsgActivity"
android:windowSoftInputMode="adjustResize"></activity>
18 AutoCompleteTextView是重型的组件,它这个类做了大量的工作,能替代PopupWindow,唯一不能做的就是,根据输入框中的内容查询数据获得cursor
<!-- android:completionThreshold="1" 提示框显示之前,用户必须输入的字符的个数,默认是2 -->
<AutoCompleteTextView
android:id="@+id/actv"
android:layout_width="0dp"
android:completionThreshold="1"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="输入号码" />
19 类$类表示内部类,内部接口; _id是联系人号码的唯一标识
20 使用CursorAdapter的条件:ListView的一个条目指向cursor的一条数据,即是listview的所有条目都来自同一个cursor
21 cursor.moveToFirst(); // 移动到第一行,游标默认在第一行的上面
22 刷新listView的方法adapter.notifyDataSetChanged() ;这个方法再次刷新listview之后会复用历史对象,注意listview的优化,getView方法里必须加上else判断;
23
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if(convertView == null){
view = getLayoutInflater().inflate(R.layout.list_item_folder, null);
}else{
view = convertView;
}
tvName.setText(names[position]);//根据条目位置索引设置名称
ivIcon.setBackgroundResource(iconIds[position]);//根据条目位置索引设置图片
//设置显示的短信的个数
tvCount.setText(""+counts[position]);//括号内是int类型的,如果不转换成字符串,系统会认为你是id,会去找的,而我们就是让它显示成数字的,所以要转成字符串
if(position % 2 !=0){// 设置背景
view.setBackgroundColor(Color.GRAY);
}else{//只要上面if else 做了一些listview的复用历史对象的优化;我们下面再if的时候,必须加上else判断,这是规定,否则刷新listview的时候会再次复用对象,页面就会出现问题
view.setBackgroundColor(Color.WHITE);
}
return view; // 如果返回null 会报空指针,而且 ,异常中只有系统代码,没有我们的代码
}
}
24 ListView中,关于逻辑处理的,尽量不要在getView()方法里面去执行;getView()里面尽量只做一些页面显示的处理
25 ContentValues类和Hashtable比较类似,它也是负责存储一些名值对,但是它存储的键值对当中的键是一个String类型,而值都是基本类型,
用于操作数据库,我们将要插入列名和对应的列值放置到一个ContentValues的实例当中
26 CursorAdapter中程序执行顺序: listView.setAdapter(adapter)--设置好之后--展示listview数据--执行--newView方法--bindView--方法
newView方法的返回值view就是bindView方法中的参数一
27 额外知识:
把java代码写在网页里就是jsp;
service是处理业务的——至—把javabean的数据取出来—至—dao数据访问对象,与数据库打交道的
包名:itcast 项目名 ,模块名、dao(接口)
user就是封装类的那个类
每个请求都对应一个servlet;
hint一点就会消失 text则不会有这功能
28 Imageview,ImageButton才有src 属性,其他没有的可以用background;
https://wangdh-PC/svn/MediaPlayer18/
stu/stu
手机影音
1 ----AS错误排除,想知道别人的和自己的为什么错误,自己可以建一个项目,对比一下--
//下面的节点数量和名称套包一致
// project build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
//2.1.3你的斯丢丢版本号 要和导入项目保持一致
classpath 'com.android.tools.build:gradle:2.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
===============================================================
//APP build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 24 //sdk版本号,1.8支持24
buildToolsVersion "24.0.2" //buildTools里面的版本号
defaultConfig {
applicationId "cast.it.mediaplayer188"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
//v7包版本看你的是支持多少,从project structure--app--dependencies可以看到
compile 'com.android.support:appcompat-v7:24.0.0-beta1'
compile 'com.google.android.gms:play-services-appindexing:8.1.0'
}
问题,更新代码
创建类 重写tostring
2 什么时候用序列化:
对象的序列化最大的目的就是进行数据传输,
序列化就是将内存中的类或者对象(你写的类都是存储在内存中的)
变成可以存储到存储媒介中的流,你将类序列化成流之后可以通过互联网传输给别人,你也可以反序列化将别人的序列化流转换成内存中的对象,就这么简单;
a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
3 通过VideoView播放视频的步骤:
a)在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件
b)调用VideoView的如下两个方法来加载指定的视频
setVidePath(String path):加载path文件代表的视频
setVideoURI(Uri uri):加载uri所对应的视频
c)调用VideoView的start()、stop()、psuse()方法来控制视频的播放
VideoView通过与MediaController类结合使用,开发者可以不用自己控制播放与暂停
4 组件之间的传输数据都是通过intent
5
6 程序调用顺序 从上往下,主线程一派,子线程一派;谁需要谁调用,每个方法里面都是至上而下的
7 Fragment类的onCreateView通過返回view來關聯布局
8 Arraylist实现了序列化 Serializable ,而List则没有实现序列化Serializable
9 ViewPager的功能就是可以使视图滑动,就像Lanucher左右滑动那样,那如何使用它呢,与ListView类似,我们也需要一个适配器,他就是PagerAdapter。ViewPager和Fragment配合使用,在滑动的时候去切换Fragment
从最简单的引导页导航,到轮转广告,到页面菜单等等,无不出现ViewPager的身影。应用广泛,简单好用,更好的交互性
适配器这个东东想必大家都不莫生,在ListView中也有适配器,listView通过重写GetView()函数来获取当前要加载的Item。而PageAdapter不太相同,毕竟PageAdapter是单个VIew的合集。
PageAdapter 必须重写的四个函数
boolean isViewFromObject(View arg0, Object arg1)
int getCount() //返回要滑动的VIew的个数
void destroyItem(ViewGroup container, int position,Object object)//从当前container中删除指定位置(position)的View;
Object instantiateItem(ViewGroup container, int position)//做了两件事,第一:将当前视图添加到container中,第二:返回当前View
10 ScrollView滚动视图是指当拥有很多内容,屏幕显示不完时,需要通过滚动条来显示的视图,
纵向滚动
<ScrollView>
<LinearLayout ........>
<TextView ...../>
<TextView ...../>
<TextView ...../>
<TextView ...../>
</LineraLayout>
</ScrollView>
横向滚动
<HorizontalScrollView >
<LinearLayout ........>
<TextView ...../>
<TextView ...../>
<TextView ...../>
<TextView ...../>
</LineraLayout>
</HorizontalScrollView >
11 XML序列化:写到文件里即是生成一个文件,称为XML序列化,从文件读取数据到内存里是解析XML
12 安卓设计模式:
(1) Application 单例模式
(2) 观察者模式 各种listener
(3) MVC 这个好理解
(4) 响应链 触摸、按键等各种事件的传递
(5) 工厂模式
(6) 适配器模式、策略模式、模板方法模式等。。。。
13 移动动画 ViewPropertyAnimator.animate(video_player_ll_top).translationY(-topLLHeight);
14 其实配了意图过滤器之后,别人则可以通过隐式意图去开启你的界面了;
15 像素 随着放大,是不变的 ;米的话是会变化的
16 Viewgrow,View 一个是容器,一个是控件;
17 drwable的子类 动画(Animation) shape等
18 Handler是线程间的通信,是子线程通知主线程更新UI
19 获得消息对象:
(1) Message msg = Message.obtain();//常用的
(2) Message msg = new Message();(不建议)因为它每次都要创建对象
(3) Message msg = handler.obtainMessage();
msg.obj = "Android群英传:神兵利器";//消息内容
msg.what = 0;消息类型
20 Handler的发消息机制:
handler.sendMessage(msg)发消息--由MessageQueue(消息队列)存储消息
--Looper(轮询器)通过loop()方法不断从消息队列中取消息来进行轮询的,也是循环获取消息,并且是死循环,来查找是否有新消息--如果有消息,就分发
给对应的handleMessage(Message msg);当消息队列中没有消息时,Looper会在那等着,会休眠,等有消息了,再去取消息;
注意:Handler,Message是有多个对象的,MessageQueue,Looper只有一个对象
里面有个消息池,消息池是通过next来连接的
Looper负责获取消息和分发回传消息
21
(1) Message 创建
Message msg = Message.obtain();
msg = new Message();(不建议)
msg = handler.obtainMessage();
handler 创建msg:
public final Message obtainMessage()
{
return Message.obtain(this);
}
this 是 Handler对象
public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}
message的对象的target属性 = handler对象. ***
obtain()方法分析 -- 看图. ****
(2) Handler创建
直接 new handler();
public Handler() {
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
}
new handler的时候 ,给内部的looper和MessageQueue赋值.
mLooper = Looper.myLooper();
通过 ActivityThread主线程创建的时候,创建的.
main():
Looper.prepareMainLooper();
**--looper.prepare() -- sThreadLocal.set(new looper());//创建了looper
new Looper();
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
***messageQueue的创建是随着looper的创建而创建的.
(3) looper如何醒来
handler.sendMessage()的时候,给looper发送消息,告诉looper该醒来.
发消息是在子线程中 -- looper在主线程. (线程间通信)
Linux PIPE管道
(4)looper取出msg之后,如何发给对应的handler对象
msg.sendToTarget();//发送给msg目标
msg 就是 对应的Handler对象
loop()如何分发消息:
msg.target.dispatchMessage(msg);
handler.dispatchMessage(msg)
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
22 Toast只能在主UI线程使用,使用下面的办法可以解决:
第一种,使用Looper,不过这种办法会终止,子线程之后的代码
//需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用,
从消息队列里取消息,处理消息。
Looper.prepare();
Toast.makeText(aActivity.this,"test",Toast.LENGTH_SHORT).show();
Looper.loop();
第二种,就是用 Handler Message
private final Handler msgHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.arg1) {
case R.string.msg_not_network:
Toast.makeText(getApplicationContext(), getResources().getString(R.string.msg_not_network), Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
23.Activity的生命周期,当点击HOme键的时候,会调用onPause()--onStop()不会调用onDestroy() ;
24 Android中GridView控件:
如果是列表(单列多行形式)的使用ListView,如果是多行多列网状形式的优先使用GridView
GirdView的一些属性:
android:numColumns="auto_fit" --------列数设置为自动
android:columnWidth="90dp",----------每列的宽度,也就是Item的宽度
android:stretchMode="columnWidth"------缩放与列宽大小同步
android:verticalSpacing="10dp"----------垂直边距
android:horizontalSpacing="10dp"-------水平边距
1、准备数据源
2、新建适配器
3、加载适配器
GridView(网格视图)是按照行列的方式来显示内容的,一般用于显示图片,图片等内容,比如实现九宫格图,用GridView是首选,也是最简单的
25 四大组件中 允许自己new出来的创建的只有广播,其他的都必须让系统创建,系统是通过反射进行创建的
如果自己new 只是一个普通的java类,则不具备上下文的能力 ;上下文的能力是系统赋予组件的
26 如果是一个接口,我们可以new出这个接口,运用匿名内部类,来实现接口的方法
27 利用绑定方式开启服务的目的,是为了方便调用服务里的方法
28 创建的接口的修饰符和接口里的方法的修饰符都必须是公有的
29 你只可以继承一个类,但你可以实现多个接口,接口相当于干爹
30 权重是线性布局的特性,相对布局的话会控件默认都在左上角
31 绑定开启服务和start开启服务两者混合开启,不仅能调用服务里的方法,还能让服务长期在后台运行;步骤为:
start开启服务--绑定服务---解绑服务
32 利用绑定服务调用服务里的方法
---------------------------------------------------------------------------------------
package zz.itcast.bindservice;
import zz.itcast.whybindservice.R;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
public class MainActivity extends Activity {
private MyServiceConn conn;
// private MyBinder2 binder;
private IService binder2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent service = new Intent(this, BindService.class);
conn = new MyServiceConn();
// 这里第一次生效
bindService(service, conn, BIND_AUTO_CREATE);
}
public void callMethodInService(View view){
// BindService bs = new BindService();
//
// bs.showToast();
// 四大组件中 允许我们自己new出来创建的只有广播 其他都必须让系统创建
// 如果自己new 就是一个普通的java类 就不具备上下文的能力了 是系统赋予组件上下文的能力
binder2.callShowToast();
}
private class MyServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
// binder = (MyBinder)service;
// (MyBinder)service 先将Ibinder--- MyBInder 向下转型
// 再将MyBInder 强转成IService 向上转型 由孙子强转成干爹
// 这里面其实做了两次类型转换
binder2 = (IService)service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
----------------------------------------------------------------------------------------
package zz.itcast.bindservice;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class BindService extends Service {
// 只要这个onBind方法返回不为null onServiceConnected马上就执行 并且系统将这个Ibinder对象传递过去
@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return new MyBinder3();
}
public class MyBinder3 extends Binder implements IService{
@Override
public void callShowToast() {
// TODO Auto-generated method stub
showToast();
}
}
@Override
public boolean onUnbind(Intent intent) {
System.out.println("onUnbind");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println("onCreate");
}
public void showToast(){
Toast toast = Toast.makeText(this, "我是服务里的吐司 你来弹我啊", 0);
toast.show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
System.out.println("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
System.out.println("onDestroy");
}
}
------------------------------------------------------------------------------------
package zz.itcast.bindservice;
public interface IService {
void callShowToast();
}
33 利用混合开启服务方式,不仅能调用服务里的方法还能,让服务长期在后台运行(音乐盒)
先start开启服务--绑定服务---解绑服务
-----------------------------------------------------------------------------
package zz.itcast.music;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class MusicService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
}
private class MyBinder extends Binder implements IPlayer{
@Override
public void callPlay() {
// TODO Auto-generated method stub
playMusic();
}
@Override
public void callPause() {
// TODO Auto-generated method stub
pauseMusic();
}
@Override
public void callRePlay() {
// TODO Auto-generated method stub
rePlayMusic();
}
@Override
public void callStop() {
// TODO Auto-generated method stub
stopMusic();
}
}
public void playMusic() {
System.out.println("播放音乐");
}
public void pauseMusic() {
System.out.println("暂停音乐");
}
public void rePlayMusic() {
System.out.println("续播音乐");
}
public void stopMusic() {
System.out.println("停止音乐");
}
}
--------------------------------------------------------------------------------------
package zz.itcast.music;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
private IPlayer player;
private MyServiceConn conn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 先start 再Bind
Intent service = new Intent(this, MusicService.class);
startService(service);
conn = new MyServiceConn();
bindService(service, conn, BIND_AUTO_CREATE);
}
public void play(View view) {
player.callPlay();
}
public void pause(View view) {
player.callPause();
}
public void replay(View view) {
player.callRePlay();
}
public void stop(View view) {
player.callStop();
}
private class MyServiceConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
player = (IPlayer) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
-----------------------------------------------------------------------
package zz.itcast.music;
public interface IPlayer {
void callPlay();
void callPause();
void callRePlay();
void callStop();
}