android 浅复制和深复制-Java Generic Deep Copy 篇

简介:

关于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);
    }
}

CloneView.java
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);
		}
	}

}



相关文章
|
16天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
29天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第30天】 随着Kotlin成为开发Android应用的首选语言,开发者社区对于其性能表现持续关注。本文通过深入分析与基准测试,探讨Kotlin与Java在Android平台上的性能差异,揭示两种语言在编译效率、运行时性能和内存消耗方面的具体表现,并提供优化建议。我们的目标是为Android开发者提供科学依据,帮助他们在项目实践中做出明智的编程语言选择。
|
1月前
|
安全 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第24天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin在Android开发中的普及,了解其与Java在性能方面的差异变得尤为重要。本文通过深入分析和对比两种语言的运行效率、启动时间、内存消耗等关键指标,揭示了Kotlin在实际项目中可能带来的性能影响,并提供了针对性的优化建议。
27 0
|
1月前
|
安全 Java Android开发
构建高效安卓应用:探究Kotlin与Java的性能对比
【2月更文挑战第22天】 在移动开发的世界中,性能优化一直是开发者们追求的关键目标。随着Kotlin在安卓开发中的普及,许多团队面临是否采用Kotlin替代Java的决策。本文将深入探讨Kotlin和Java在安卓平台上的性能差异,通过实证分析和基准测试,揭示两种语言在编译效率、运行时性能以及内存占用方面的表现。我们还将讨论Kotlin的一些高级特性如何为性能优化提供新的可能性。
52 0
|
23天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
在开发高性能的Android应用时,选择合适的编程语言至关重要。近年来,Kotlin因其简洁性和功能性受到开发者的青睐,但其性能是否与传统的Java相比有所不足?本文通过对比分析Kotlin与Java在Android平台上的运行效率,揭示二者在编译速度、运行时性能及资源消耗方面的具体差异,并探讨在实际项目中如何做出最佳选择。
17 4
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第24天】 在移动开发领域,性能优化一直是开发者关注的重点。随着Kotlin的兴起,许多Android开发者开始从传统的Java转向Kotlin进行应用开发。本文将深入探讨Kotlin与Java在Android平台上的性能表现,通过对比分析两者在编译效率、运行时性能和内存消耗等方面的差异。我们将基于实际案例研究,为开发者提供选择合适开发语言的数据支持,并分享一些提升应用性能的最佳实践。
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第22天】随着Kotlin在Android开发中的普及,开发者们对其性能表现持续关注。本文通过深入分析Kotlin与Java在Android平台上的执行效率,揭示了二者在编译优化、运行时性能以及内存占用方面的差异。通过实际案例测试,为开发者提供选择合适编程语言的参考依据。
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能对比
【2月更文挑战第28天】 在Android开发领域,Kotlin作为一种现代编程语言,逐渐取代了传统的Java语言。本文通过深入分析Kotlin和Java在Android平台上的性能差异,揭示两者在编译效率、运行速度以及内存消耗等方面的比较结果。我们将探讨Kotlin协程如何优化异步编程,以及Kotlin Extensions对提升开发效率的贡献。同时,文中还将介绍一些性能优化的实践技巧,帮助开发者在Kotlin环境下构建更加高效的Android应用。
|
1月前
|
安全 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第27天】 在Android开发领域,Kotlin和Java一直是热门的编程语言选择。尽管两者都可以用于创建高质量的Android应用程序,但它们在性能方面的差异一直是开发者关注的焦点。本文通过深入分析Kotlin与Java在Android平台上的运行效率、编译时间及内存消耗等方面的表现,揭示两种语言在实际应用中的性能差异,帮助开发者根据项目需求做出更明智的选择。
|
1月前
|
Java 测试技术 Android开发
构建高效安卓应用:探究Kotlin与Java的性能差异
【2月更文挑战第22天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin成为Android官方推荐的开发语言,许多项目开始从Java转向Kotlin。本文将深入探讨Kotlin与Java在安卓平台上的性能表现,通过实际案例和基准测试,分析两种语言在编译效率、运行速度、内存消耗等方面的差异。此外,我们还将讨论如何利用Kotlin的优势来提升应用性能,并提出针对性的优化建议。