关于Java Generic Deep Copy 在java中的应用和注意事项,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7039425
而关于在android程序中通过clone方法来进行浅复制和深复制,请参考:http://blog.csdn.net/yang_hui1986527/article/details/7036818
众所周知,android上层使用的是java语言,因此理论上于Java Generic Deep Copy 方法,同样适用于android程序中对象的深度拷贝。但是,上次在一个android的demo中使用试图通过该方法来进行深度拷贝,一直未成功。出错提示如下:
W/ActivityManager( 154): Launch timeout has expired, giving up wake lock!
W/ActivityManager( 154): Activity idle timeout for HistoryRecord{40540f08 com.clone/.CloneActivity}
E/dalvikvm( 3080): Could not find class 'javax.print.attribute.standard.PrinterStateReason', referenced from method com.ajexperience.utils.DeepCopyUtil.a
W/dalvikvm( 3080): VFY: unable to resolve instanceof 97 (Ljavax/print/attribute/standard/PrinterStateReason;) in Lcom/ajexperience/utils/DeepCopyUtil;
D/dalvikvm( 3080): VFY: replacing opcode 0x20 at 0x011d
D/dalvikvm( 3080): VFY: dead code 0x011f-0131 in Lcom/ajexperience/utils/DeepCopyUtil;.a (Ljava/lang/Object;Ljava/lang/Object;Lcom/ajexperience/utils/DeepCopyUtil$a;)Ljava/lang/Object;
W/System.err( 3080): java.lang.RuntimeException: com.ajexperience.utils.DeepCopyException: java.lang.NoSuchFieldException: modifiers
W/System.err( 3080): at com.clone.CloneUtil.getDeepCloneUtil(CloneUtil.java:14)
W/System.err( 3080): at com.clone.CloneUtil.<init>(CloneUtil.java:8)
W/System.err( 3080): at com.clone.CloneView.<init>(CloneView.java:24)
W/System.err( 3080): at com.clone.CloneActivity.onCreate(CloneActivity.java:12)
W/System.err( 3080): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
W/System.err( 3080): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
W/System.err( 3080): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
W/System.err( 3080): at android.app.ActivityThread.access$1500(ActivityThread.java:123)
W/System.err( 3080): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
W/System.err( 3080): at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err( 3080): at android.os.Looper.loop(Looper.java:130)
W/System.err( 3080): at android.app.ActivityThread.main(ActivityThread.java:3835)
W/System.err( 3080): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err( 3080): at java.lang.reflect.Method.invoke(Method.java:507)
W/System.err( 3080): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
W/System.err( 3080): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
W/System.err( 3080): at dalvik.system.NativeStart.main(Native Method)
W/System.err( 3080): Caused by: com.ajexperience.utils.DeepCopyException: java.lang.NoSuchFieldException: modifiers
W/System.err( 3080): at com.ajexperience.utils.DeepCopyUtil.<init>(SourceFile:99)
W/System.err( 3080): at com.clone.CloneUtil.getDeepCloneUtil(CloneUtil.java:12)
W/System.err( 3080): ... 16 more
W/System.err( 3080): Caused by: java.lang.NoSuchFieldException: modifiers
W/System.err( 3080): at java.lang.ClassCache.findFieldByName(ClassCache.java:446)
W/System.err( 3080): at java.lang.Class.getDeclaredField(Class.java:666)
W/System.err( 3080): at com.ajexperience.utils.DeepCopyUtil.<init>(SourceFile:95)
W/System.err( 3080): ... 17 more
D/dalvikvm( 424): GC_EXPLICIT freed 5K, 51% free 3666K/7367K, external 0K/0K, paused 95ms
I/ActivityManager( 154): Displayed com.clone/.CloneActivity: +20s115ms
于是,通过邮件向作者咨询该问题。今天,终于又收到作者的邮件,通知Java Generic Deep Copy 有更新,让我再试试。
下载最新版DeepCopyUtil-1.5,替换以前的库,运行成功。
主要思路:
1、创建TextBox,然后根据TextBox复制出一个对象TextBox2(点击屏幕,进行复制);
2、改变TextBox2的位置,方便观察比较差异。
3、改变TextBox2内部文本的位置。如果是浅复制,那么TextBox2内部文本改变位置的同时,TextBox内部文本的位置会随着改变。否则,如果是深度复制,TextBox内部文本的位置不会改变。
效果如下:
注:请注意文本“test”在文本框内的位置。
深复制:
源程序:
CloneActivity.java
package com.clone;
import android.app.Activity;
import android.os.Bundle;
public class CloneActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
CloneView mCloneView = new CloneView(this);
setContentView(mCloneView);
}
}
package com.clone;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CloneView extends View {
private Document mDocument = null;
public Paint mPaint= null;
public TextBox mTextBox = null;
public TextBox mTextBox2 = null;
private CloneUtil mCloneUtil = null;
public CloneView(Context context) {
super(context);
mDocument = new Document();
mPaint = new Paint();
try {
mCloneUtil = new CloneUtil();
} catch (Exception e) {
e.printStackTrace();
}
initData();
}
public CloneView(Context context, AttributeSet attrs) {
super(context, attrs);
mDocument = new Document();
mPaint = new Paint();
try {
mCloneUtil = new CloneUtil();
} catch (Exception e) {
e.printStackTrace();
}
initData();
}
public CloneView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDocument = new Document();
}
public void initData()
{
PointF textpos = new PointF(30,30);
String text = new String("test");
mTextBox = new TextBox(50, 50, 100, 100, textpos, text);
mDocument.add(mTextBox);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
mDocument.draw(canvas, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
{
if (mCloneUtil != null) {
mTextBox2 = (TextBox) mCloneUtil.clone(mTextBox); //深克隆
}
if(mTextBox2 != null)
{
mTextBox2.moveBound();
mTextBox2.changeData();
mDocument.add(mTextBox2);
}
}
invalidate();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return super.onTouchEvent(event);
}
}
Document.java
package com.clone;
import java.util.Vector;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Document {
private Vector<Object> objs = null;
public Document() {
objs = new Vector<Object>();
}
public void add(Object obj){
objs.add(obj);
}
void draw(Canvas canvas, Paint paint) {
canvas.save();
for (int i = 0; i < objs.size(); i++) {
Object obj = objs.get(i);
obj.draw(canvas, paint);
}
canvas.restore();
}
}
Object.java
package com.clone;
import android.graphics.Canvas;
import android.graphics.Paint;
public abstract class Object{
protected float posx = 0;
protected float posy =0;
protected float width = 0;
protected float height = 0;
public Object() {
posx = 0;
posy =0;
width = 0;
height = 0;
}
public Object(float posx,float posy,float width,float height){
this.posx = posx;
this.posy = posy;
this.width = width;
this.height = height;
}
public void moveBound() {
this.posx += 100;
this.posy += 100;
}
abstract void draw(Canvas canvas,Paint paint);
abstract void changeData();
}
TextBox.java
package com.clone;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
public class TextBox extends Object{
private PointF mtextpos = null;
private String mtextString = null;
public TextBox() {
posx = 0;
posy =0;
width = 0;
height = 0;
mtextpos = new PointF();
mtextString = new String();
}
public TextBox(float posx, float posy, float width, float height,PointF textpos,String text) {
this.posx = posx;
this.posy = posy;
this.width = width;
this.height = height;
mtextpos = new PointF(textpos.x,textpos.y);
mtextString = new String(text);
}
@Override
void draw(Canvas canvas, Paint paint) {
canvas.save();
paint.setColor(Color.BLUE);
paint.setStyle(Style.STROKE);
canvas.drawRect(posx, posy, posx+width, posy+height, paint);
canvas.translate(posx, posy);
paint.setColor(Color.BLACK);
paint.setTextSize(20);
canvas.drawText(mtextString, mtextpos.x, mtextpos.y, paint);
canvas.restore();
}
@Override
void changeData() {
if(mtextpos != null)
mtextpos.offset(20, 50);
}
}
CloneUtil.java
package com.clone;
import com.ajexperience.utils.DeepCopyException;
import com.ajexperience.utils.DeepCopyUtil;
public class CloneUtil {
private DeepCopyUtil deepCopyUtil = getDeepCloneUtil();
private DeepCopyUtil getDeepCloneUtil() {
try {
return new DeepCopyUtil();
} catch (DeepCopyException e) {
throw new RuntimeException(e);
}
}
public Object clone(Object object) {
try {
return deepCopyUtil.deepCopy(object);
} catch (DeepCopyException e) {
throw new RuntimeException(e);
}
}
}
欢迎大家关注我的微信公众号:
微信公众号:sn0wdr1am