Context
简介
Context是提供了关于应用环境全局信息的抽象类
通过它的对象, 才可以操作系统或应用的相关资源
如何使用
通过它自己调用方法context.xxxx()
或者将context作为实参传进去
功能
context最主要的功能是加载和访问资源
启动或停止Activity/Service
context.startAtivity
context.startService
发送广播/注册广播接收器
加载布局/创建视图对象
new EditText(context)
View.inflate(context, layoutid, null)
获取应用环境全局信息
Context getApplicationContext()
Application activity.getApplication()
getApplicationInfo()
getContentResolver()
getPackageManager()
getPackageName()
getResources()
getAssets()
getSharedPreferences()
String getString(int id)
getSystemService(String serviceName)
实现分类
Activity
Service
Application
.....
Application
特点
每个应用只有一个此对象, 单例
context类型的对象都可以得到此对象
应用全局数据内存级共享容器
生命周期
创建
应用启动且其对象不存在(创建应用的进程之后)
死亡
应用退出不会销毁Application对象
应用的进程被主动或被动杀死时(在内存不足时,系统会优先将空进程干掉)
区别
主要区别是:不同的功能作用,生命周期不一样
Application的生命周期比其他的长很多
那我们应该如何进行选择呢?
使用的时候是选择Activity还是getApplicationContext()?
显示Dialog时必须用Activity
创建视图对象/加载布局最好使用Activity
显示地图时必须用ApplicationContext
其它绝大的情况下两者都可
选择applicationContext肯定没问题
选择Actvity可能会导致Activity对象不能回收, 导致内存泄露
就好比如之前的那个欢迎页面,我们在主界面里面通过发延迟消息来启动另外一个界面
然后我们在延迟消息处理之前退出界面,但是延迟消息还是会处理
然后还是会启动另外一个界面的,这里就是出现了内存泄漏
activity在退出之后本应该是要死亡被回收的,但是因为
发了延迟消息,里面的handler能看到activity,而handler有消息还没处理
消息在消息队列里面,消息队列一直存在,所以activity和handler还不是垃圾对象
还不能进行回收,所以现在内存泄漏,直到消息被处理完成
ANR(Application Not Responding)
Application Not Responding
这个就是程序无响应状态
原因是程序在UI线程中对用户的操作响应执行的时间过长
类型
按键或触摸事件在特定时间内无响应(大概5S在上)
BroadcastReceiver在特定时间内无法处理完成(大概10S以上) onReceive()
Service在特定的时间内无法处理完成(大概20S以上)
解决
不要在UI线程中做长时间的事
耗时的操作放入分线程中处理
服务和广播接收器的生命周期回调方法都是UI线程中执行
内存泄露和内存溢出
内存泄露
一块内存占用着没有释放, 但无法再用到它
使用Handler发延迟消息, 退出时不移除
内存溢出
当申请的内存超过能给你的内存时就会抛出此异常
加载很多图片/大图片
横竖屏
默认情况下, 横竖屏切换时Activity会被销毁并重新创建
如何不让Activity不被销毁?
在配置文件里面相应的activity里面配置
configChanges="orientation|keyboardHidden|screenSize"
然后会自动调用onConfigurationChanged()
如何只竖屏或横屏?
竖屏: screenOrientation="portrait"
横屏: screenOrientation="landscape"
横竖屏切换:
横屏: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
竖屏: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
得到当前手机的方向
getResources().getConfiguration().orientation
package com.jane.orientation;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
Log.e("TAG", "onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy()
{
Log.e("TAG", "onDestroy()");
super.onDestroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
int orientation = newConfig.orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT)
{
Toast.makeText(this, "竖屏", 0).show();
} else
{
Toast.makeText(this, "横屏", 0).show();
}
}
public void switchOrientation(View v)
{
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}