1 引用函数 setResult和 onActivityResult处理机制
实现原理,在第二个Activity的返回事件中返回数据,第一个Activity中重构onActivityResult方法,在重构该方法的事件中,感受返回的数据,作出不一样的处理。以达到自动更新第一个Activity的效应。详细状况参考以下的介绍。当前两个activity,MainAcivity和SecondActivity;
A MainAcivity的重要代码:
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
Log.v("android.abc", "!!!!!"+MainActivity.this.toString());
bundle.putString("uid", MainActivity.this.toString());
intent.putExtras(bundle);
startActivityForResult(intent,GET_CODE);
}
B.SecondActivity中,在OnClickListener中
findViewById(R.id.button).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
setResult(RESULT_OK,(new Intent()).setAction(uid));
finish();
}
});
B.在MainActivity中,重写onActivityResult方法;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == GET_CODE)
{
if(resultCode == RESULT_CANCELED)
{
text2.setText("点击了返回");
}
else
{
if (data != null)
{
text2.setText("获得第二个activity返回的结果:\n"+data.getAction());
}
}
}
}
其中static final private int GET_CODE = 0;是我自定义的常量,用来区分当前返回的是哪一个activity的结果;下面是类SecondActivity的代码:
public class SecondActivity extends Activity{
String uid;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Bundle bundle = this.getIntent().getExtras();
if (bundle != null)
{
uid = bundle.getString("uid");
}
findViewById(R.id.button).setOnClickListener(
new View.OnClickListener()
{
@Override
public void onClick(View v)
setResult(RESULT_OK,(new Intent()).setAction(uid));
finish();
}
});
}
}
//
public void startActivityForResult (Intent intent, int requestCode)
启动一个Activity且传递一个requestCode值,在本Activity推出时,在启动的Activity的onActivityResult()的方法中将会被调用到这个
传递的这个requestCode值。忽略这个requestCode值,实际上startActivityForResult跟startActivity(Intent)没有什么差异
注意,该方法只适用那些须要有一个返回值的Intent。在其余协议(如ACTION_MAIN或ACTION_VIEW),你可能不会获得当你指望的结果。举个例子
,若是 你启动的activity 采用了singleTask模式,它将不会运行在你的任务,所以你将收到一个取消的结果。做为一种特殊的状况下,在初始化
activity的onCreate(Bundle savedInstanceState)/onResume() of your activity期间,若是你调用参数requestCode > = 0的
startActivityForResult(),那么在窗口中将不会显示返回来的结果,这是为了在链接到另外一个activity时避免闪烁
protected void onActivityResult (int requestCode, int resultCode, Intent data)
Called when an activity you launched exits, giving you the requestCode you started it with, the resultCode
it returned, and any additional data from it. The resultCode will be RESULT_CANCELED if the activity explicitly returned
that, didn't return any result, or crashed during its operation.
You will receive this call immediately before onResume() when your activity is re-starting.
Parameters
requestCode The integer request code originally supplied to startActivityForResult(), allowing you to identify who this
result came from.
resultCode The integer result code returned by the child activity through its setResult().
data An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
//
2 引用函数 onResume处理机制
在每个可能在改变语言区域的Activity 以前显示出来的Activity中,重载onResume()并加入以下代码:
oldLocale = mLocale;
Locale locale = getLocaleFormPreference(this);
if(oldLocale!=null && !oldLocale.equals(locale)) {
Bundle bundle = new Bundle();
activity.onSaveInstanceState(bundle);
Intent intent = new Intent(this, this.getClass());
intent.putExtra("InstanceState", bundle);
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
startActivity(intent);
finish();
}
并在onCreate(Bundle savedInstanceState)最后加入和动态更新时彻底相同的代码。mLocale 其实是在onCreate(Bundle savedInstanceState)中,指定的Locale 时(也就是上一节最初时那段代码)记住的。而若是,你的Activity启动须要要一些原有Intent 的数据,别忘了自行导入
3 利用Handler刷新界面
Android提供了Invalidate方法实现界面刷新,可是Invalidate不能直接在线程中调用,由于他是违背了单线程模型:Android UI操做并非线程安全的,而且这些操做必须在UI线程中调用。实例化一个Handler对象,并重写handleMessage方法调用invalidate()实现界面刷新;而在线程中经过sendMessage发送界面更新消息。
// 在onCreate()中开启线程
new Thread(new GameThread()).start();、
// 实例化一个handler
Handler myHandler = new Handler()
{
//接收到消息后处理
public void handleMessage(Message msg)
{
switch (msg.what)
{
case Activity01.REFRESH:
mGameView.invalidate(); //刷新界面
break;
}
super.handleMessage(msg);
}
};
class GameThread implements Runnable
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
Message message = new Message();
message.what = Activity01.REFRESH;
//发送消息
Activity01.this.myHandler.sendMessage(message);
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
}
4 使用postInvalidate()刷新界面
使用postInvalidate则比较简单,不须要handler,直接在线程中调用postInvalidate便可。
class GameThread implements Runnable
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
//使用postInvalidate能够直接在线程中更新界面
mGameView.postInvalidate();
}
}
}
5 多线程和双缓冲
A.不使用多线程和双缓冲
这种状况最简单了,通常只是但愿在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法便可。系统会自动调用 View的onDraw()方法。
B.使用多线程和不使用双缓冲
这种状况须要开启新的线程,新开的线程就很差访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.
这时候你须要建立一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。android.os.Handler是能发送和处理消息的,你须要在Activity中发出更新UI的消息,而后再你的Handler(可使用匿名内部类)中处理消息(由于匿名内部类能够访问父类变量,你能够直接调用View对象中的invalidate()方法)。也就是说:在新线程建立并发送一个Message,而后再主线程中捕获、处理该消息。
Java代码
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
. timeViewHandler.sendMessage(Message.obtain(timeViewHandler, MSG_UPDATE));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
Java代码
public class TimeViewHandler extends Handler {
private TextView timeView;
public TextView getTimeView() {
return timeView;
}
public void setTimeView(TextView timeView) {
this.timeView = timeView;
}
public TimeViewHandler(TextView timeView) {
super();
this.timeView = timeView;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE:
timeView.setText(DateHelper.getNow("kk:mm:ss"));
timeView.invalidate();
break;
}
super.handleMessage(msg);
. }
}
C 使用多线程和双缓冲
Android中SurfaceView是View的子类,她同时也实现了双缓冲。你能够定义一个她的子类并实现SurfaceHolder.Callback接口。因为实现SurfaceHolder.Callback接口,新线程就不须要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法能够锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),仍是比较方便得。
Java代码
public class TouchDrawView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder holder;
private TouchDrawListener listener;
public TouchDrawListener getListener() {
return listener;
}
public void setListener(TouchDrawListener listener) {
this.listener = listener;
}
public TouchDrawView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(this);
listener = new TouchDrawListener(holder);
listener.setShape(TouchDrawListener.SHAPE_LINE);
listener.setShape_style(TouchDrawListener.SHAPE_STYLE_FILL);
this.setOnTouchListener(listener);//设置屏幕事件监听器
this.setLongClickable(true);//不设置将没法捕捉onFling()事件
setFocusable(true);//设置键盘焦点
. setFocusableInTouchMode(true);//设置触摸屏焦点
}
public TouchDrawView(Context context, AttributeSet as) {
this(context);
}
@Override
protected void onDraw(Canvas canvas) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//关键部分
Canvas canvas = holder.lockCanvas(null);//获取画布
canvas.drawColor(Color.WHITE);//白色背景
holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
} android