您好,登录后才能下订单哦!
https://blog.csdn.net/shangming150/article/details/77914110
https://www.jianshu.com/p/2b3785484d7f
ToolBar与ActionBar
https://www.jianshu.com/p/81d0bcb282cb
1.什么是Activity
官方文档是这么说的:An Activity
is an application component that provides a screen with which
users can interact in order to do something, such as dial the phone, take a photo, send an email, or
view a map. Each activity is given a window in which to draw its user interface. The window
typically fills the screen, but may be smaller than the screen and float on top of other
windows.
大致意思是说:Activity是一个应用程序组件,给用户提供一个屏幕让用户可以与之交互做一些事
情。
2.Activity的生命周期
下面这张图是官方文档提供的Activity的生命周期的图:
·onCreate 方法 当Activity启动的是调用
·onDestroy方法 当Activity销毁的时候调用
·onStart 方法 当Activity可见的时候调用
·onStop 方法 当Activity 不可见的时候调用
·onResume 方法 当Activity上的按钮 获得焦点 可以被点击的时候调用
·onPause 方法 当Activity 上的按钮 失去焦点 按钮不可以被点击的时候调用
·onRestart 方法 当界面被重新加载的时候调用 注意这个方法
■手机按键对应的Activity生命周期的回调方法
如果点击BACK键,会调用Activity的onPause()、onStop()、onDestroy()方法,Activity
会注销掉。
如果点击HOME键,会调用Activity的onPause()、onStop()方法,但不会执行onDestroy() 方法,程序会运行在后台。如果应用程序没有被系统杀死,那么再点击应用程序图标会调用Activity的onRestart()、onStart()、OnResume()方法。
■特殊的回调方法组合
如果打开第一个Activity之后,不关闭它,开启另外一个Activity(非透明的),会调用第一个Activity的onPause()、onStop()方法。
如果打开第一个Activity之后,不关闭它,开启另外一个Activity(透明的),会调用第一个
Activity的onPause()方法,而不会去调用onStop()方法,因为第一个Activity还是可见的。如果关
闭透明的Activity,第一个Activity只会回调onResume()方法。
■切屏对应的Activity生命周期的回调方法
手机在切屏的时候,会先销毁,再创建.走onPause()、onStop()、onDestroy()方法,再走onCreate
()、onStart()、onResume()方法。这一过程就相当于关闭并重新进入应用一样,那么如何防止手机
在切屏时生命周期发生改变呢?
第一种方式:把Activity页面的朝向写死,通过这个属性
android:screenOrientation="portrait" portrait代表竖屏 landscape代表横屏
朝向写死,在手机上方向是不能改变的,但是在AVD上仍可以切屏,只是生命周期没有变化。
第二种方式:android:configChanges="orientation|keyboardHidden|screenSize"
3.Activity的清单配置
如果想让Activity成为应用程序的入口,需要将activity的意图过滤器配置如下:
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
Android允许程序有多个activity作为应用程序的入口,只要activity配置了以上的意图过滤器,就会在手机桌面上创建多个应用程序图标,点击图标会进入对应的activity界面。
如果activity节点没有设置自己的label和icon,会默认使用application节点的label和icon。
4.Activity的页面跳转及数据传递
拓展:话说android Activity之间数据传递 http://blog.csdn.net/maylian7700/article/details/7323993
注意的问题,序列化的类中还有自定义的类,则这个类也要序列化,否则会出错.
■启动Activity传数据和取数据
本Activity:传数据,通过Intent对象的setData()和putExtra()方法封装数据至Intent对象。
被调用的的Activity:取数据,通过Activity类的getIntent()方法先得到开启这个Activity的
Intent对象,也就是本Activity里传数据用到的Intent对象,然后通过
Intent对象的getXxxExtra()方法得到数据。
■启动Activity的2种方式
第一种:不需要被启动的Activity返回数据
startActivity(intent);
第二种:需要被启动的Activity返回数据
startActivityForResult(intent, int类型的请求码);
对于第二种Activity的启动方式,需要思考的两个问题?
1)被调用的Activity怎么返回数据?
首先,调用者Activity启动被调用的Activity的方式是
startActivityForResult(intent, int类型的请求码);
其次,在被调用的Activity里面,创建Intent对象,将要返回的数据封装进Intent对
象,调用Activity类的setResult(int resultCode, Intent data)方法返回Intent对象。
如:
//将数据返回 Intent intent = new Intent(); intent.putExtra("phone", phone); setResult(10, intent);
2)调用者Activity怎么获取被调用的Activity所返回的数据?
通过复写Activity的onActivityResult方法可以得到其它的一个或多个Activity返
回的数据.
如:
上面的截图是Android官方文档的截图,利用了双重判断确定是哪个对象返回的数据,这样显
得更加严密. 返回的数据就存储在方法中的参数data中,调用Intent对象的方法取出即可.
5.应用1_短信大全
需求:将一些好的短信显示到ListView上,点击某一条短信,就跳到手机的短信发送页面,并把
ListView选中条目的内容添加到短信发送页面的短信内容中.
分析:这个需求首先涉及到ListView的使用,然后跳到手机短信发送页面,涉及到隐式意图启动系
统应用,并且要将本应用的数据传递到系统应用里,涉及到页面跳转和数据传递.
效果图:
假如我点击了ListView短信列表的第2条短信,然后就跳转到短信发送页面
核心代码:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //得到点击的item对应的数据 String msg = objects[position]; //利用隐式意图,跳转到短信发送页面。 //怎么写过滤条件,查源码。。。。 /* <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>*/ Intent intent = new Intent(); //设置意图对象的过滤条件 intent.setAction("android.intent.action.SEND"); intent.addCategory("android.intent.category.DEFAULT"); intent.setType("text/plain"); //传递数据给××× intent.putExtra("sms_body", msg); /* * 不小心用了setDataAndType(Uri.parse(msg),"text/plain");结果×××的联系人处是data,发送内容什么也没有。 * */ startActivity(intent); }
那么问题来了,上面意图对象的过滤条件及传递数据格式我是怎么知道的呢?
1)先打开Logcat,然后打开手机短信发送页面,会看到Locat上打印这样一行信息(如果没有
打印任何信息,先安装一个自己的应用,然后重新打开系统的短信发送页面。):
2)然后去系统应用源码里找到短信发送应用Sms,在清单文件里找到ComposeMessageActivity
的配置
短信发送页面有很多的过滤器,都是用于发现不同格式数据的(用mimetype属性来约束),
我们这里就只需要文本类型的数据,就选择mimetype为text/plain的进行过滤了。
知道了意图对象的过滤器,那么就可以为意图对象设置过滤信息
3)但是,怎么给intent传递数据呢?那么就得看短信发送页面的Activity是如何获取调用
它的Intent的数据的?
通过在ComposeMessageActivity.java里搜索getStringExtra可以得到×××是根据
sms_body键名来获取短信内容的。
所以Intent在putExtra时采用的键名是“sms_body”。
6.应用2_×××
需求:做一个如下图所示的×××,布局采用混合线性布局。
功能1:在主UI界面中点击“添加联系人”那个+号按钮,就弹出一个窗体列出联系人(是
模拟数据,学到内容提供者即可获取手机真正的联系人),选择一个联系人后关闭
选择联系人页面,并将选择的联系人电话返回显示到主UI界面的文本框中。
功能2:在主UI界面中点击“插入模板”按钮,就弹出一个窗体列出一些短信,选择一条
短信后关闭短信大全页面,将将选择的短信返回显示到主UI界面的短信内容文本框
分析:上面的需求,也涉及到页面跳转和数据传递,不同的是被调用的页面在关闭的同时还要
向调用者(主UI界面)返回选择的数据。那么,这个应用要求的技术有以下几点:
1)主UI界面在启动其它Activity的时候,应当使用startActivityForResult的方式,并
复写Activity的onActivityResult方法。
2)两个返回数据的ListView都要设置item点击事件,在事件中返回数据并关闭页面。
3)发送短信的功能
核心代码:
1)短信模板页面
因为ListView只需显示单列数据,适配器就直接使用ArrayAdapter了。
//模拟数据 final String[] objects = {短信内容,为节省空间就不写了。}; //得到 listview ListView lv_templates = (ListView) findViewById(R.id.lv_templates); //绑定lv的适配器,用ArrayAdapter。 lv_templates.setAdapter(new ArrayAdapter<String>(this, R.layout.item_activity_sms_template, R.id.item, objects)); //注册lv的item点击事件 //要实现的逻辑:获取数据,返回数据,关闭当前activity lv_templates.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //得到数据 String content = objects[position]; //通过intent返回数据 Intent intent = new Intent(); intent.putExtra("content", content); setResult(20, intent); //关闭当前activity finish(); } });
2)选择联系人页面
//模拟数据 final List<Map<String, String >> lists = new ArrayList<Map<String, String >> (); for(int i = 0 ; i < 20; i++) { Map<String,String> map = new HashMap<String, String>(); map.put("name","联系人" + i); map.put("phone",new Random().nextInt(252523)+""); lists.add(map); } //得到 listview ListView lv_contacts = (ListView) findViewById(R.id.lv_contacts); //绑定lv的适配器,用SimpleAdapter,可以添加多个textview。 lv_contacts.setAdapter(new SimpleAdapter(this, lists, R.layout.item_activity_contacts,new String[]{"name","phone"}, new int[] {R.id.tv_name,R.id.tv_phone})); //注册lv的item点击事件 //要实现的逻辑:获取数据,返回数据,关闭当前activity lv_contacts.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //拿到相应item的数据,通过lists集合,只要电话号码。 String phone = lists.get(position).get("phone"); //将数据返回 Intent intent = new Intent(); intent.putExtra("phone", phone); setResult(10, intent); //关闭当前activity finish(); } });
3)主UI页面
★获取模板页面和联系页面数据并显示
protected void onActivityResult(int requestCode, int resultCode, Intent data) { //通过resultCode来区别不同的activity返回的intent对象 if(resultCode == 10) { et_name.setText(data.getStringExtra("phone")); } else if (resultCode == 20){ et_content.setText(data.getStringExtra("content")); } }
★发送短信
通过SmsManager这个类,注意它的获取方式是通过SmsManager.getDefault方法
与打电话不同,打电话是通过隐式意图来调用的。
记得要在清单文件里加上权限:
<uses-permission android:name="android.permission.SEND_SMS"/>
public void send() { //TODO 短信发送 //得到联系人和发送内容 String name = et_name.getText().toString().trim(); String content = et_content.getText().toString().trim(); //利用一个类SmsManager来发送短信 注意不要用过时的SmsManager SmsManager smsManager = SmsManager.getDefault(); //短信内容过长,就得切割之后再一条条发送。 ArrayList<String> divideMessage = smsManager.divideMessage(content); for(String msg : divideMessage) { smsManager.sendTextMessage(name, null, msg, null, null); } }
7.Android中的任务栈
栈 :先进后出
队列 先进先出
任务栈 :是用来维护Activity的 ,| Activity是用来维护用户的操作体验的
打开一Activity 叫 进栈
关闭一个Activity 出栈
我们用户操作的Activity 永远是栈顶的Activity
说我们应用程序退出了 实际上是任务栈清空了
一般情况下 一个应用程序对应一个任务栈
8.Android中4种启动模式
1.android:launchMode="standard"(默认)
2.singletop 单一顶部模式 在activity的配置文件中设置android:launchMode="singleTop"
如果任务栈的栈顶存在这个要开启的activity,不会重新的创建activity,而是复用已经存在
的activity。保证栈顶Activity如果存在,不会重复创建。
应用场景:浏览器的书签
3. singetask 单一任务栈,在当前任务栈里面只能有一个实例存在
当开启activity的时候,就去检查在任务栈里面是否有实例已经存在,如果有实例存在就复用
这个已经存在的activity,并且把这个activity上面的所有的别的activity都清空,复用这个已经
存在的activity。保证整个任务栈里面一个Activity只有一个实例存在
应用场景:浏览器的activity
如果一个activity的创建需要占用大量的系统资源(cpu,内存)一般配置这个activity为
singletask的启动模式。webkit内核 c代码
4.singleInstance启动模式非常特殊, activity会运行在自己的任务栈里面,并且这个任务栈里面
只有一个实例存在
如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance
应用场景: 来电页面 有道词典
和Activity相关的其它技术点:
1.当 Activity 以全屏模式运行时,如何允许 Android 系统状态栏在顶层出现,而不迫使 Activity 重新布局让
出空间?
http://www.zhihu.com/question/19760889
8.Android中4种启动模式
1.设置activity不可点击
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
9.LoadManager
https://blog.csdn.net/bangyiqing/article/details/17475179
http://www.voidcn.com/article/p-zyuprzwa-bsv.html
9.Android屏幕旋转导致Activity重建的几种解决办法
https://blog.csdn.net/a_salty_fish/article/details/91491147
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。