android - 常用知识点以及代码片段(不断更新)
获取LayoutInflater对象三种方法:
1、LayoutInflater inflater=getLayoutInflater();
2、LayoutInflater inflater=(LayoutInflater)mContext.getSystemServic(LAYOUT_INFLATER_SERVICE);
3、LayoutInflater inflater=LayoutInflater.from(context); //这种方法在重写BaseAdapter时常用
如果要用ListActivity,则 Activity的Layout文件中必须包括一个(只能一个)ListView,且ListView的id= "@id/android:list"。(继承ListActivity时)
margin:外边距
padding:内边距
像素/1.5等于dip
EditText属性之一:android:background="@android:drawable/editbox_background"
当LinearLayout 是horizontal ,并且里面的控件使用了layout_width="fill_parent" ,第二组控件会挡在屏幕的右边,那也就是看不到了。
LayoutInflater的作用是,把一个View的对象与XML布局文件关联并实例化。
View的对象实例化之后,可以通过findViewById()查找布局文件中的指定Id的组件。
android:gravity="center_vertical"表示:将对象纵向居中,不改变其大小。垂直对齐方式:垂直方向上居中对齐。
android:gravity="center_horizontal"表示:将对象横向居中,不改变其大小。水平对齐方式:水平方向上居中对齐。
按比例显示LinearLayout内各个子控件,需设置android:layout_width="0dp",如果为竖直方向的设置android:layout_height="0dp"。在这种情况下某子个控件占用LinearLayout的比例为:本控件weight值 / LinearLayout内所有控件的weight值的和。
使用ListView记得加上属性:android:cacheColorHint="#00000000"或者
//设置背景透明
list.setCacheColorHint(Color.TRANSPARENT);
设置listView点击或滑动为白色(去除默认的黄色):android:listSelector="#fff"
在EditText中加入<requestFocus></requestFocus>可以使之获取焦点
中间加横线:
textView.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG );
底部加横线:
textView.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG );
隐藏状态栏:
final Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
隐藏标题栏:
requestWindowFeature(Window.FEATURE_NO_TITLE);
隐藏ScrollBar:
布局:android:ScrollBars="none"
代码:
void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled)
void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled)
获取手机号/手机串号:
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId();
String tel = tm.getLine1Number();
标题栏进度指示器:
在使用时我们首先需要在setContentView之前声明
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
在需要显示进度时调用
setProgressBarIndeterminateVisibility(true);
停止时调用
setProgressBarIndeterminateVisibility(false);
在listView的item中有button时,需要设置button为没有焦点。
android:divider="@null" 该属性作用是每一项之间需要设置一个图片做为间隔,或是去掉item之间的分割线
android:fadingEdge="none" 设置后没有阴影
总结一下列表布局的关键部分:
1.布局文件中定义ListView
2.Adapter用来将数据填充到ListView
3.要填充到ListView的数据,这些数据可以字符串、图片、控件等等
其中Adapter是 ListView和数据源之间的桥梁,根据数据源的不同Adapter可以分为三类:
1.String[]: ArrayAdapter
2.List<Map<String,?>>: SimpleAdapter
3.数据库Cursor: SimpleCursorAdapter
//清空手机上cookie
CookieSyncManager.createInstance(getApplicationContext());
CookieManager.getInstance().removeAllCookie();
自定义标题:
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); //声明使用自定义标题
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);//自定义布局赋值
//Android 开发之 ClipboardManager
//获取剪贴板管理服务
ClipboardManager cm =(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
//将文本数据复制到剪贴板
cm.setText(message);
//读取剪贴板数据
cm.getText();
//30分钟执行一次服务
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
long interval = DateUtils.MINUTE_IN_MILLIS * 30;
long firstWake = System.currentTimeMillis() + interval;
am.setRepeating(AlarmManager.RTC,firstWake, interval, pendingIntent);
//MD5加密算法
public class MD5 {
public static String getMD5(String val) throws NoSuchAlgorithmException{
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(val.getBytes());
byte[] m = md5.digest();//加密
return getString(m);
}
private static String getString(byte[] b){
StringBuffer sb = new StringBuffer();
for(int i = 0; i < b.length; i ++){
sb.append(b[i]);
}
return sb.toString();
}
}
//Activity界面切换添加动画特效
//实现淡入淡出的效果
overridePendingTransition(Android.R.anim.fade_in,android.R.anim.fade_out);
overridePendingTransition(Android.R.anim.fade_in,android.R.anim.fade_out);
//由左向右滑入的效果
overridePendingTransition(Android.R.anim.slide_in_left,android.R.anim.slide_out_right);
overridePendingTransition(Android.R.anim.slide_in_left,android.R.anim.slide_out_right);
//实现zoomin和zoomout,即类似iphone的进入和退出时的效果
overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
overridePendingTransition(R.anim.zoomin, R.anim.zoomout);
新建zoomin.xml文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.android.com/apk/res/android"
Android:interpolator="@android:anim/decelerate_interpolator">
<scale Android:fromXScale="2.0" android:toXScale="1.0"
Android:fromYScale="2.0" android:toYScale="1.0"
Android:pivotX="50%p" android:pivotY="50%p"
Android:duration="@android:integer/config_mediumAnimTime" />
</set>
新建zoomout.xml文件
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.android.com/apk/res/android"
Android:interpolator="@android:anim/decelerate_interpolator"
Android:zAdjustment="top">
<scale Android:fromXScale="1.0" android:toXScale=".5"
Android:fromYScale="1.0" android:toYScale=".5"
Android:pivotX="50%p" android:pivotY="50%p"
Android:duration="@android:integer/config_mediumAnimTime" />
<alpha Android:fromAlpha="1.0" android:toAlpha="0"
Android:duration="@android:integer/config_mediumAnimTime"/>
</set>
//设置透明度(这是窗体本身的透明度,非背景)
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.alpha=0.3f;
getWindow().setAttributes(lp);
//alpha在0.0f到1.0f之间。1.0完全不透明,0.0f完全透明
//设置黑暗度
WindowManager.LayoutParams lp=getWindow().getAttributes();
lp.dimAmount=0.5f;
getWindow().setAttributes(lp);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
//dimAmount在0.0f和1.0f之间,0.0f完全不暗,1.0f全暗
//设置背景模糊
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
//以上设置对dialog对话框同样有效
//设置星星样式的checkbox
style="?android:attr/starStyle"
//让字体闪烁
private int clo = 0;
public void spark() {
final TextView touchScreen = (TextView) findViewById(R.id.TextView01);// 获取页面textview对象
Timer timer = new Timer();
TimerTask taskcc = new TimerTask(){
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if (clo == 0) {
clo = 1;
touchScreen.setTextColor(Color.TRANSPARENT); // 透明
} else {
if (clo == 1) {
clo = 2;
touchScreen.setTextColor(Color.RED);
} else {
clo = 0;
touchScreen.setTextColor(Color.GREEN);
}
}
}
});
}
};
timer.schedule(taskcc, 1, 300); // 参数分别是delay(多长时间后执行),duration(执行间隔)
}
}
//从输入流中获取数据并以字节数组返回
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public class StreamTool {
/**
* 从输入流获取数据
* @param inputStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inputStream) throws Exception {
byte[] buffer = new byte[1024]; //你可以根据实际需要调整缓存大小
int len = -1;
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
while( (len = inputStream.read(buffer)) != -1 ){
outSteam.write(buffer, 0, len);
}
outSteam.close();
inputStream.close();
return outSteam.toByteArray();
}
}
//安装apk文件
private void installAPK(File file) {
Intent intent = newIntent(Intent.ACTION_VIEW);
Uri data =Uri.fromFile(file);
String type ="application/vnd.android.package-archive";
intent.setDataAndType(data,type);
startActivity(intent);
}
//卸载apk文件
private void uninstallAPK(String packageName){
Intent intent = newIntent(Intent.ACTION_VIEW);
Uri data = Uri.parse("package:"+ packageName);
intent.setData(data);
startActivity(intent);
}
//编辑图片大小,保持图片不变形。
public static Bitmap resetImage(BitmapsourceBitmap,int resetWidth,int resetHeight){
int width =sourceBitmap.getWidth();
int height =sourceBitmap.getHeight();
int tmpWidth;
int tmpHeight;
float scaleWidth =(float)resetWidth / (float)width;
float scaleHeight =(float)resetHeight / (float)height;
float maxTmpScale = scaleWidth>= scaleHeight ? scaleWidth : scaleHeight;
//保持不变形
tmpWidth = (int)(maxTmpScale *width);
tmpHeight = (int)(maxTmpScale *height);
Matrix m = new Matrix();
m.setScale(maxTmpScale,maxTmpScale, tmpWidth, tmpHeight);
sourceBitmap =Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(),sourceBitmap.getHeight(), m, false);
//切图
int x = (tmpWidth -resetWidth)/2;
int y = (tmpHeight -resetHeight)/2;
returnBitmap.createBitmap(sourceBitmap, x, y, resetWidth,resetHeight);
}
//从SIM卡中获取联系人
private Cursor getContacts() {
Uri uri = Uri.parse("content://sim/adn");
String[] projection = new String[] { "name", "phone" };
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;
return managedQuery(uri, projection, selection, selectionArgs,sortOrder);
}
//检查网络是否连接
public boolean checkIntent(){
ConnectivityManager mannager=(ConnectivityManager)
this.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo info=mannager.getActiveNetworkInfo();
if(info==null || !info.isConnected()){
return false;
}
if(info.isRoaming()){
return true;
}
return true;
}
//<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
//取得屏幕信息
DisplayMetrics dm = new DisplayMetrics();
dm = this.getResources().getDisplayMetrics();
//获得屏幕宽度
int screenWidth = dm.widthPixels;
//获得屏幕高度
int screenHeight = dm.heightPixels;
//获取屏幕方向
Configuration newConfig = getResources().getConfiguration();
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
//横屏
}else if(newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
//竖屏
}else if(newConfig.hardKeyboardHidden == Configuration.KEYBOARDHIDDEN_NO){
//键盘没关闭。屏幕方向为横屏
}else if(newConfig.hardKeyboardHidden == Configuration.KEYBOARDHIDDEN_YES){
//键盘关闭。屏幕方向为竖屏
}
//开机自动启动
public class BootReceiver extends BroadcastReceiver {
private PendingIntent mAlarmSender;
@Override
public void onReceive(Context context, Intent intent) {
// 在这里干你想干的事(启动一个Service,Activity等),本例是启动一个定时调度程序,
每30分钟启动一个Service去更新数据
mAlarmSender = PendingIntent.getService(context, 0, new Intent(context,
RefreshDataService.class), 0);
long firstTime = SystemClock.elapsedRealtime();
AlarmManageram=(AlarmManager)context.getSystemService(Activity.ALARM_SERVICE);
am.cancel(mAlarmSender);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 30*60*1000,
mAlarmSender);
}
}
<receiver android:name=".service.BootReceiver">
<intent-filter>
<!-- 系统启动完成后会调用-->
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
</intent-filter>
</receiver>
HttpURLConnection对象
1)创建一个URL对象:URL url = new URL(http://www.baidu.com );
2)利用HttpURLConnection对象从网络中获取网页数据:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3)设置连接超时:conn.setConnectTimeout(6*1000);
4)对响应码进行判断:if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");
5)得到网络返回的输入流:InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK");
7)conn.disconnect();
--记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作.
--返回的响应码200,是成功.
--利用ByteArrayOutputStream类,将得到的输入流写入内存.
--在Android中对文件流的操作和JAVA SE上面是一样的.
2.从Internet获取文件
利用HttpURLConnection对象,从网络中获取文件数据.
1)创建URL对象,并将文件路径传入:URL url = new URL(http://photocdn.sohu.com/20100125/Img269812337.jpg );
2)创建HttpURLConnection对象,从网络中获取文件数据:HttpURLConnection conn = (HttpURLConnection)
3)设置连接超时:conn.setConnectTimeout(6* 1000);
4)对响应码进行判断:if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");
6)将得到的文件流写出:outStream.write(buffer, 0, len);
总结:
--在对大文件的操作时,要将文件写到SDCard上面,不要直接写到手机内存上.
--操作大文件是,要一遍从网络上读,一遍要往SDCard上面写,减少手机内存的使用.这点很重要,面试经常会被问到.
--对文件流操作完,要记得及时关闭.
2)创建URL对象:URL realUrl = new URL(requestUrl);
3)通过HttpURLConnection对象,向网络地址发送请求:HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
4)设置容许输出:conn.setDoOutput(true);
5)设置不使用缓存:conn.setUseCaches(false);
7)设置维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");
8)设置文件字符集:conn.setRequestProperty("Charset", "UTF-8");
9)设置文件长度:conn.setRequestProperty("Content-Length", String.valueOf(data.length));
10)设置文件类型:conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
11)以流的方式输出.
总结:
--发送POST请求必须设置允许输出
--不要使用缓存,容易出现问题.
--在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头.
4.向Internet发送xml数据
XML格式是通信的标准语言,Android系统也可以通过发送XML文件传输数据.
1)将生成的XML文件写入到byte数组中,并设置为UTF-8:byte[] xmlbyte = xml.toString().getBytes("UTF-8");
总结:
--我们使用的是用HTML的方式传输文件,这个方式只能传输一般在5M一下的文件.
--传输大文件不适合用HTML的方式,传输大文件我们要面向Socket编程.确保程序的稳定性
1)将地址和参数存到byte数组中:byte[] data = params.toString().getBytes();
5. HttpURLConnection中如何设置网络超时
Java中可以使用HttpURLConnection来请求WEB资源。
HttpURLConnection对象不能直接构造,需要通过URL.openConnection()来获得HttpURLConnection对象,示例代码如下:
String szUrl = "http://www.baidu.com/";
URL url = new URL(szUrl);
HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
HttpURLConnection是基于HTTP协议的,其底层通过socket通信实现。如果不设置超时(timeout),在网络异常的情况下,可能会导致程序僵死而不继续往下执行。可以通过以下两个语句来设置相应的超时:
System.setProperty("sun.net.client.defaultConnectTimeout", 超时毫秒数字符串);
System.setProperty("sun.net.client.defaultReadTimeout", 超时毫秒数字符串);
其中: sun.net.client.defaultConnectTimeout:连接主机的超时时间(单位:毫秒)
sun.net.client.defaultReadTimeout:从主机读取数据的超时时间(单位:毫秒)
例如:
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
System.setProperty("sun.net.client.defaultReadTimeout", "30000");
JDK 1.5以前的版本,只能通过设置这两个系统属性来控制网络超时。在1.5中,还可以使用HttpURLConnection的父类URLConnection的以下两个方法:
setConnectTimeout:设置连接主机超时(单位:毫秒)
setReadTimeout:设置从主机读取数据超时(单位:毫秒)
例如:
HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
urlCon.setConnectTimeout(30000);
urlCon.setReadTimeout(30000);
需要注意的是,笔者在JDK1.4.2环境下,发现在设置了 defaultReadTimeout的情况下,如果发生网络超时,HttpURLConnection会自动重新提交一次请求,出现一次请求调用,请求 服务器两次的问题(Trouble)。我认为这是JDK1.4.2的一个bug。在JDK1.5.0中,此问题已得到解决,不存在自动重发现象。
//自动更新代码示例:
public class Update extends BaseActivity {
public ProgressDialog pBar;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.update);
Dialog dialog = new AlertDialog.Builder(Update.this)
.setTitle("系统更新")
.setMessage("发现新版本,请更新!")
// 设置内容
.setPositiveButton("确定",// 设置确定按钮
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
pBar = new ProgressDialog(Update.this);
pBar.setTitle("正在下载");
pBar.setMessage("请稍候...");
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
downFile("http://url:8765/OA.apk");
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// 点击"取消"按钮之后退出程序
}
}).create();// 创建
// 显示对话框
dialog.show();
}
void downFile(final String url) {
pBar.show();
new Thread() {
public void run() {
HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) {
File file = new File(
Environment.getExternalStorageDirectory(),
"OA.apk");
fileOutputStream = new FileOutputStream(file);
byte[] buf = new byte[1024];
int ch = -1;
int count = 0;
while ((ch = is.read(buf)) != -1) {
// baos.write(buf, 0, ch);
fileOutputStream.write(buf, 0, ch);
count += ch;
if (length > 0) {
}
}
}
fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
down();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
void down() {
handler.post(new Runnable() {
public void run() {
pBar.cancel();
update();
}
});
}
void update() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File("/sdcard/OA.apk")),
"application/vnd.android.package-archive");
startActivity(intent);
}
}
应用程序动态全屏和退出全屏
让程序全屏的方法,大家都知道,那是静态的,程序运行之初就申明了。但是如果有这样的需求:要在程序运行的过程中,执行了某个操作而使之全屏,然后还需要退出全屏,怎么做?
如下:
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
修改window的LayoutParams参数,然后加上FLAG_LAYOUT_NO_LIMITS标志,就OK了。window会自动重新布局,呈现全屏的状态。
要退出全屏,只需要清除刚才加上的FLAG_FULLSCREEN参数,然后去掉FLAG_LAYOUT_NO_LIMITS标志。
如下
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
android监听文件和目录的创建删除移动等事件
android.os下的FileObserver类是一个用于监听文件访问、创建、修改、删除、移动等操作的监听器,基于linux的inotify。 FileObserver 是个抽象类,必须继承它才能使用。每个FileObserver对象监听一个单独的文件或者文件夹,如果监视的是一个文件夹,那么文件夹下所有的文件和级联子目录的改变都会触发监听的事件。
所能监听的事件类型如下:
ACCESS,即文件被访问
MODIFY,文件被 修改
ATTRIB,文件属性被修改,如 chmod、chown、touch 等
CLOSE_WRITE,可写文件被 close
CLOSE_NOWRITE,不可写文件被 close
OPEN,文件被 open
MOVED_FROM,文件被移走,如 mv
MOVED_TO,文件被移来,如 mv、cp
CREATE,创建新文件
DELETE,文件被删除,如 rm
DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
ALL_EVENTS,包括上面的所有事件
这些都是FileObserver的静态共有属性。
下面举个例子说明一下其用法。
比如,我要监听sd卡的目录创建事件,新建一个类SDCardListener继承FileObserver:
import android.os.FileObserver;
import android.util.Log;
/**
* sd卡上的目录创建监听器
* @author chroya
*
*/
public class SDCardListener extends FileObserver {
public SDCardListener(String path) {
/*
* 这种构造方法是默认监听所有事件的,如果使用super(String,int)这种构造方法,
* 则int参数是要监听的事件类型.
*/
super(path);
}
@Override
public void onEvent(int event, String path) {
switch(event) {
case FileObserver.ALL_EVENTS:
Log.d("all", "path:"+ path);
break;
case FileObserver.CREATE:
Log.d("Create", "path:"+ path);
break;
}
}
}
onEvent是回调,系统监听到事件后会触发此事件,参数event就是上面所说的事件类型,根据类型,我们可以做相应的处理,参数path就是触发事件的目录。
然后使用它:
SDCardListener listener = new SDCardListener("/sdcard");
//开始监听
listener.startWatching();
/*
* 在这里做一些操作,比如创建目录什么的
*/
//最后停止监听
listener.stopWatching();
如果要在onEvent中做较多操作,最好用线程去做
,以免因为阻塞接收不到后面的事件。
最后补充一点,比较重要
:
FileObserver对象必须保持一个引用,确保不被垃圾收集器回收掉,否则就不会触发事件了。
Android获取其他包的Context
Android中有Context的概念,想必大家都知道。Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、 获取classLoader、获取资源等等。如果我们得到了一个包的Context对象,那我们基本上可以做这个包自己能做的大部分事情。
那我们能得到吗?很高兴的告诉你,能!
Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。
这个方法有两个参数:
1。packageName 包名,要得到Context的包名
2。flags
标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。
CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思
是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。
下面给个小例子,执行另外一个包里面的某个类的方法。
另外一个包的包名是chroya.demo,类名Main,方法名print,代码如下:
package chroya.demo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void print(String msg) {
Log.d("Main", "msg:"+ msg);
}
}
本包的调用Main的print方法的代码块如下
Context c = createPackageContext("chroya.demo", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
//载入这个类
Class clazz = c.getClassLoader().loadClass("chroya.demo.Main");
//新建一个实例
Object owner = clazz.newInstance();
//获取print方法,传入参数并执行
Object obj = clazz.getMethod("print", String.class).invoke(owner, "Hello");
ok,这样,我们就调用了chroya.demo包的Main类的print方法,执行结果,打印出了Hello。
/**
* 判断日期格式是否正确
*/
public static boolean IsDateFormat(String dataStr) {
boolean state = false;
try {
java.text.SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd");
dFormat.setLenient(false);
java.util.Date d = dFormat.parse(dataStr);
state = true;
} catch (ParseException e) {
e.printStackTrace();
state = false;
}
return state;
}
/**
* 计算date之前n天的日期
*/
public static Date getDateBefore(Date date, int n) {
Calendar now = Calendar.getInstance();
now.setTime(date);
now.set(Calendar.DATE, now.get(Calendar.DATE) - n);
return now.getTime();
}
/**
* 得到几天后的时间
*/
public static Date getDateAfter(Date d, int day) {
Calendar now = Calendar.getInstance();
now.setTime(d);
now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
return now.getTime();
}