深入分析:Fragment与Activity交互的几种方式(一,使用Handler)

这里我不再详细介绍那写比较常规的方式,例如静态变量,静态方法,持久化,application全局变量,收发广播等等。

首先我们来介绍使用Handler来实现Fragment与Activity 的交互。

第一步,我们需要在Activity中定义一个方法用来设置Handler对象。

public void setHandler(Handler handler) {
mHandler = handler;
}

第二步,在Fragment中的回调函数onAttach()中得到Fragment所在Activity,并调用setHandler方法,设置Handler。该Handler在Fragment中定义,用来接收消息与Fragment进行交互。

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = (MainActivity) activity;
mActivity.setHandler(mHandler);
}


public Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
text.setText((String) msg.obj);
break;
}
};

};

然后我们可以在Activity中发送消息给Fragment中的Hanlder进行交互。

public void inter(View view) {
Message msg = new Message();
msg.obj = edit.getText().toString();
msg.what = 1;
mHandler.sendMessage(msg);
}

我写了一个Demo与大家分享,链接地址:http://download.csdn.net/detail/huangyabin001/7559807

点击下载demo

首先我们需要在Activity中动态添加Fragment时,用Bundle封装我们需要传递的数据。

public void button(View view) {
ArgFragment arg = new ArgFragment();
Bundle bundle = new Bundle();
bundle.putString("arg", edit.getText().toString());
arg.setArguments(bundle);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.layout_fragment, arg);
ft.commit();
}

然后在Fragment的回调函数中通过Fragment提供的方法getArguments()取出Bundle对象。

text = (TextView) view.findViewById(R.id.text);
Bundle bundle = getArguments();
text.setText(bundle.getString("arg"));


针对本文也写了一个Demo,下载地址:http://download.csdn.net/detail/huangyabin001/7560031

点击打开链接

 

深入分析:Fragment与Activity交互的几种方式(三,使用接口)


第一步:我们需要在Fragment中定一个接口,并确保我们的容器Activity实现了此接口:


public interface onTestListener {
public void onTest(String str);
}


@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// 这个方法是用来确认当前的Activity容器是否已经继承了该接口,如果没有将抛出异常
try {
mCallback = (onTestListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnHeadlineSelectedListener");
}
}

第二步:在我们的容器Activity中实现此接口,并实现接口中的方法。

public class MainActivity extends Activity implements onTestListener {

......

@Override
public void onTest(String str) {
text.setText(str);
}

第三步:我们在fragment执行某些特定的操作时,调用接口中声明的方法。

@Override
public void onClick(View v) {
mCallback.onTest(edit.getText().toString());
}


完整代码链接地址:http://download.csdn.net/detail/huangyabin001/7560291点击打开链接


 在我们开发Android App应用的时候,有些需求需要我们启动其他的App来处理一些逻辑,例如我们需要根据一个地址来调用系统或者相关的地图Map App,这样我们不用在自己的App中编写相应的功能,而是通过Intent来发送一些请求,调用相关的应用来处理这些请求。并且我们称这种Intent为隐式的Intent;这种隐式的Intent是相对于显式的Intent来讲的。显式的Intent我们都比较熟悉,显式的Intent常常需要声明类的名称,而隐式的Intent我们需要声明一个Action,我们Action中定义了我们想要处理的请求。与Action相关联的还有data,例如我们需要查看的地址,或者我们需要拨打的电话号码,或者我们需要发送邮件的邮件地址等等。例如:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. Uri number = Uri.parse("tel:5551234");Intent callIntent = new Intent(Intent.ACTION_DIAL, number);  

        上述代码中,我们通过startActivity()来调用Phone App,并进行拨打(5551234)的通话操作。当然这里还有很多案例,这里主要是从API 文档中摘录的了。贴在这里供大家参考。

查看地图:

<span class="com">// Map point based on address</span><span class="pln">
</span><span class="typ">Uri</span><span class="pln"> location </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Uri</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">"geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"</span><span class="pun">);</span><span class="pln">
</span><span class="com">// Or map point based on latitude/longitude</span><span class="pln">
</span><span class="com">// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level</span><span class="pln">
</span><span class="typ">Intent</span><span class="pln"> mapIntent </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Intent</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">ACTION_VIEW</span><span class="pun">,</span><span class="pln"> location</span><span class="pun">);</span>

浏览网页:

<span class="typ">Uri</span><span class="pln"> webpage </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Uri</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">"http://www.android.com"</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Intent</span><span class="pln"> webIntent </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Intent</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">ACTION_VIEW</span><span class="pun">,</span><span class="pln"> webpage</span><span class="pun">);</span>
发送邮件:
<span class="typ">Intent</span><span class="pln"> emailIntent </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Intent</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">ACTION_SEND</span><span class="pun">);</span><span class="pln">
</span><span class="com">// The intent does not have a URI, so declare the "text/plain" MIME type</span><span class="pln">
emailIntent</span><span class="pun">.</span><span class="pln">setType</span><span class="pun">(</span><span class="pln">HTTP</span><span class="pun">.</span><span class="pln">PLAIN_TEXT_TYPE</span><span class="pun">);</span><span class="pln">
emailIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">EXTRA_EMAIL</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">String</span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="str">"jon@example.com"</span><span class="pun">});</span><span class="pln"> </span><span class="com">// recipients</span><span class="pln">
emailIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">EXTRA_SUBJECT</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Email subject"</span><span class="pun">);</span><span class="pln">
emailIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">EXTRA_TEXT</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Email message text"</span><span class="pun">);</span><span class="pln">
emailIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">EXTRA_STREAM</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Uri</span><span class="pun">.</span><span class="pln">parse</span><span class="pun">(</span><span class="str">"content://path/to/email/attachment"</span><span class="pun">));</span><span class="pln">
</span><span class="com">// You can also attach multiple items by passing an ArrayList of Uris</span>
创建一个事件通知:
<span class="typ">Intent</span><span class="pln"> calendarIntent </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Intent</span><span class="pun">(</span><span class="typ">Intent</span><span class="pun">.</span><span class="pln">ACTION_INSERT</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Events</span><span class="pun">.</span><span class="pln">CONTENT_URI</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Calendar</span><span class="pln"> beginTime </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Calendar</span><span class="pun">.</span><span class="pln">getInstance</span><span class="pun">().</span><span class="kwd">set</span><span class="pun">(</span><span class="lit">2012</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">19</span><span class="pun">,</span><span class="pln"> </span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="lit">30</span><span class="pun">);</span><span class="pln">
</span><span class="typ">Calendar</span><span class="pln"> endTime </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Calendar</span><span class="pun">.</span><span class="pln">getInstance</span><span class="pun">().</span><span class="kwd">set</span><span class="pun">(</span><span class="lit">2012</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span class="lit">19</span><span class="pun">,</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln"> </span><span class="lit">30</span><span class="pun">);</span><span class="pln">
calendarIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">CalendarContract</span><span class="pun">.</span><span class="pln">EXTRA_EVENT_BEGIN_TIME</span><span class="pun">,</span><span class="pln"> beginTime</span><span class="pun">.</span><span class="pln">getTimeInMillis</span><span class="pun">());</span><span class="pln">
calendarIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">CalendarContract</span><span class="pun">.</span><span class="pln">EXTRA_EVENT_END_TIME</span><span class="pun">,</span><span class="pln"> endTime</span><span class="pun">.</span><span class="pln">getTimeInMillis</span><span class="pun">());</span><span class="pln">
calendarIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">Events</span><span class="pun">.</span><span class="pln">TITLE</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Ninja class"</span><span class="pun">);</span><span class="pln">
calendarIntent</span><span class="pun">.</span><span class="pln">putExtra</span><span class="pun">(</span><span class="typ">Events</span><span class="pun">.</span><span class="pln">EVENT_LOCATION</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Secret dojo"</span><span class="pun">);</span>

        此外,我们在定义我们的Intent的时候,要尽可能的详细,例如我们希望调用系统的图片查看器浏览图片,我们应该定义MIME type" image/*.",以防止会启动map app进行查看。而且如果没有app来响应我们的请求,我们的app就会崩溃。

        因此为了防止我们的app发送intent没有其他app来响应而导致应用异常退出,我们在发送intent前进行验证。为了验证是否有app的Activity来响应我们的Intent请求,我们需要调用queryIntentActivities()来进行验证。这个方法会返回一个list,我们通过判断list是否为空来验证,这样我们可以安全的使用Intent来实现不同App之间Activity的交互。如果没有响应的Acitivty来响应,我们可以提供一些链接给用户进行下载安装。验证方法如下:

       

<span class="typ">PackageManager</span><span class="pln"> packageManager </span><span class="pun">=</span><span class="pln"> </span><code><a target=_blank target="_blank" href="file:///D:/Android/docs/reference/android/content/Context.html#getPackageManager()" style="text-decoration: none; color: rgb(12, 137, 207);"><span class="pln">getPackageManager</span><span class="pun">()</span></a></code><span class="pun">;</span>

<span class="typ">List</span><span class="pun"><</span><span class="typ">ResolveInfo</span><span class="pun">></span><span class="pln"> activities </span><span class="pun">=</span><span class="pln"> packageManager</span><span class="pun">.</span><span class="pln">queryIntentActivities</span><span class="pun">(</span><span class="pln">intent</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">);</span>

<span class="kwd">boolean</span><span class="pln"> isIntentSafe </span><span class="pun">=</span><span class="pln"> activities</span><span class="pun">.</span><span class="pln">size</span><span class="pun">()</span><span class="pln"> </span><span class="pun">></span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span>

下面我们通过具体的案例来使用隐式的Intent,使不同的App中的Activity进行交互。

首先我们创建第一个项目appsend,我们创建一个按钮,并且在点击事件中创建Intent,并设置Action和type,并添加onActivityResult()来接收我们从第二个应用中返回的数据。

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public void button(View view) {  
  2.     Intent intent = new Intent();  
  3.     intent.setAction(Intent.ACTION_VIEW);  
  4.     intent.setType("test/");  
  5.     startActivityForResult(intent, 2);  
  6. }  

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
  3.         super.onActivityResult(requestCode, resultCode, data);  
  4.         switch (requestCode) {  
  5.         case 2:  
  6.             switch (resultCode) {  
  7.             case Activity.RESULT_OK:  
  8.                 text.setText("URI:" + data.getDataString());  
  9.                 break;  
  10.             }  
  11.             break;  
  12.         }  
  13.     }  

第二步:我们创建第二个应用,并且在清单文件中进行配置Intent-filter;

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <activity  
  2.             android:name="com.example.appreceiver.MainActivity"  
  3.             android:label="@string/app_name" >  
  4.             <intent-filter>  
  5.                 <action android:name="android.intent.action.MAIN" />  
  6.   
  7.                 <category android:name="android.intent.category.LAUNCHER" />  
  8.             </intent-filter>  
  9.             <intent-filter>  
  10.                 <action android:name="android.intent.action.VIEW" />  
  11.                 <data android:mimeType="test/*" />  
  12.   
  13.                 <category android:name="android.intent.category.DEFAULT" />  
  14.             </intent-filter>  
  15.         </activity>  

第三步:在第二个Activity中监听返回按钮,并传回数据。

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  3.     switch (keyCode) {  
  4.     case KeyEvent.KEYCODE_BACK:  
  5.         Intent result = new Intent("com.example.appsend",  
  6.                 Uri.parse("content://result_uri"));  
  7.         setResult(Activity.RESULT_OK, result);  
  8.         finish();  
  9.         break;  
  10.     }  
  11.     return super.onKeyDown(keyCode, event);  
  12. }  
具体案例下载地址为:http://download.csdn.net/detail/huangyabin001/7561309 点击打开链接



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值