详解Android Activity之间切换传递数据的方法
前面照着android系统的裁剪图片的功能自己写了一个相似的工具。功能是大体上实现了,但留下了一个调用的问题:如何从我的程序调用这个裁剪工具,并且获得裁剪后的图片呢?
其实这个也很简单了,就是intent的基础用法。
先上个图(界面依旧没优化,难看就难看吧):
起始activity,打开图片选择窗口,随便选择一张图片
下面是跳转到裁剪界面
按下crop按钮,退出activity,回到原来界面,并显示裁剪后的图
流程就是这样,也算模拟了系统裁剪功能的整体过程。下面就是实现功能的关键代码和说明了。
这里先称主程序为a,调用的子程序为b。
b是自己写的程序,调用他就需要定制自己的activity action。系统的action都对应一个action字符串,比如在intent类中定义的一些action常量:
public static final string action_main = "android.intent.action.main"; public static final string action_view = "android.intent.action.view"; public static final string action_edit = "android.intent.action.edit"; public static final string action_call = "android.intent.action.call"; public static final string action_call_emergency = "android.intent.action.call_emergency";
intent的构造方法中,会有一些如:intent.setclass(activity.this, x.class);的方法。但我不太喜欢这种方式。
除此之外常用的构造方法就是
public intent(string action); public intent(string action, uri uri);
使用string,uri这种参数类型的intent对象称为隐式intent对象,即,通过intent类的构造方法并未指定intent的目标是哪一个activity,这些目标要依靠在androidmanifest.xml文件中的配置信息才能确定。也就是说,action所指的目标可能不止一个,或者说再androidmanifest.xml文件中可以配置多个接收同一个action的activity action。
在androidmanifest.xml中一般文件格式如下:
<application android:allowbackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/apptheme" > <activity android:name="com.example.crop_image_my.mainactivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application>
其中<action>标签指定一个系统定义的activity action。该action表示在应用程序启动时第一个启动的activity需要接收这个action。也就是说这个动作是android应用程序启动主窗口的动作。
因为需要自己的action启动裁剪程序,所以我在上面的xml中另外加了下面一段:
<intent-filter> <action android:name="com.example.crop_image_my.copper" /> <data android:scheme="crop" /> <category android:name="android.intent.category.default" /> </intent-filter>
保留.main是我需要程序单独运行也可以(不知道删掉的话会怎样,没测试)
上面<data>标签定义一个scheme,所以后面的uri可以写作 crop://something
哦对,上面的是b的配置文件,a要启动b嘛。
下面在a中就可以调用b的intent了:
private void startmycropintent(string path) throws filenotfoundexception { intent intent = new intent("com.example.crop_image_my.copper", uri.parse("crop://" + path)); startactivityforresult(intent, ); }
上面构造intent就不说了,参数是前面配置文件里的。要想启动新的activity,使用startactivity()就可以,但为了能获取到返回值,就要用startactivityforresult()方法,在onactivityresult()进行处理。
第二个参数12是请求代码,对应onactivityresult(int requestcode,int resultcode, intent data)中第一个参数。这个数字可以随便写,但建议用资源写,比如某个按钮触发startactivityforresult(),就可以把这个按钮的r.id.button1当请求码(其实用什么都行了,只要方便识别)。
好,启动activity后,注意参数有一个uri,这个uri就是我选择的图片的路径,在裁剪的方法b中里要获取这个uri:
if (getintent().getdata() != null) { imgpath = getintent().getdata().getpath(); // 参见uri的组成形式资料 log.v("<dbw>", imgpath); mycropview.setbmppath(imgpath); }
写在oncreate里,在构造的时候就取得这个值并使用。
下面是关闭activity。在b里面写。直接放代码吧
@override public void onclick(view v) { // todo auto-generated method stub switch (v.getid()) { case r.id.btn_crop: bitmap croppedimage = mycropview.getcroppedimage(); croppedimageview.setimagebitmap(croppedimage); savecroppedimage(croppedimage); // return to the last activity log.v("<dbw>", newfilepath); getintent().putextra("newpath", newfilepath); setresult(, getintent()); break; case r.id.btn_cancel: setresult(); break; default: break; } finish(); }
裁剪之后先保存图片,然后通过getintent().putextra()方法把图片路径存在intent里。“newpath”是随便起的名,作为取数据的标识。finish()是关闭这个activity。参数20是onactivityresult(int requestcode,int resultcode, intent data)的第二个参数。
最后获取截到的图片,在a写:
@override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); switch (requestcode) { case : if (resultcode == ) { string path = data.getextras().getstring("newpath"); log.v("<dbw>", "get------" + path); bitmap bmp = bitmapfactory.decodefile(path); iv.setimagebitmap(bmp); } else if (resultcode == ) { toast toast = toast.maketext(this, "您取消了操作", toast.length_long); toast.show(); } break; default: break; } }
switch是针对不同的activity(当前只启动一个,标识码是12)。再对不同的resultcode做不同处理。
前面用了putextra设置数据,这里就用data.getextra方法获取bundle对象,在根据需要用getxxx方法获得不同的数据。
就是这么个过程。
4.28.2015
另一个简单方法:
同一个项目里建2个activity,eclipse 项目右击->new->others->android->android activity
manifest.xml:
<application android:allowbackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/apptheme" > <activity 启动显示的 android:name=".mainactivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <activity 切换的 android:name=".showmessage" android:label="@string/title_activity_display_message" android:parentactivityname=".mainactivity" > <meta-data android:name="android.support.parent_activity" android:value="com.example.android_switchactivity.mainactivity" /> </activity> </application>
在mainactivity中添加:
public final static string extra_message = "com.example.android_switchactivity.message"; 这个string可以任意赋值,但要保证唯一intent intent = new intent(this, showmessage.class); edittext met = (edittext)findviewbyid(r.id.edit_message); string message = met.gettext().tostring(); intent.putextra(extra_message, message); startactivity(intent);
在第2个activity添加:
intent intent = getintent(); string message = intent.getstringextra(mainactivity.extra_message); textview mtv = new textview(this); mtv.settextsize(40); mtv.settext(message);
推荐阅读
-
详解Android Activity之间切换传递数据的方法
-
Android应用中图片浏览时实现自动切换功能的方法详解
-
Android开发之利用Intent实现数据传递的方法
-
详解Android中Intent传递对象给Activity的方法
-
在不同Activity之间传递数据的四种常用方法
-
Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解
-
详解Android Activity之间切换传递数据的方法
-
Android开发之利用Intent实现数据传递的方法
-
Android 两个Fragment之间传递数据实例详解
-
在不同Activity之间传递数据的四种常用方法