Android 返回前面的Activity时且它也能自动更新

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) {  
      }  
  }  
























































转载于:https://my.oschina.net/xiahuawuyu/blog/94310

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值