安卓-获取全局上下文

来源:互联网 发布:js获取input file对象 编辑:程序博客网 时间:2024/05/19 03:29

一、实现获取全局上下文

什么情况下需要使用全局上下文,不能通过参数传过来,但是做其他工作又用到这个参数,这种情况下就需要使用全局上下文,一般情况下都是可以通过参数传进去的。

比如说封装一个工具类,工具类中需要用到上下文,可以通过参数传进去,也可以在工具类中使用全局上下文。以获取getApplicationContext();这个为例。为了便于管理,将其定义在Application中。总结下使用步骤:

1)自定义Application,如:MyApplication

2)实现获取全局上下文的方法

3)AndroidManifest.xml中引用自定义的MyApplication

4)使用获取全局上下文的方法

下面详细说明:

1)自定义一个Application类

import android.app.Application;import android.content.Context;/** * Created by wangwentao on 2017/2/21. */public class MyApplication extends Application {    private static Context context;//全局上下文    @Override    public void onCreate(){        context = getApplicationContext();    }    //获取全局的上下文    public static Context getContext(){        return context;    }}

2)实现获取全局上下文的方法

MyApplication这个类中定义了一个getContext()方法,用于获取全局的上下文

3)AndroidManifest.xml中引用自定义的MyApplication

<application
        android:name=".main.base.MyApplication"

4)使用获取全局上下文的方法

通过写一个小demo,在主界面中添加三个按钮,分别演示传Activity所在的上下文,不传上下文,使用全局上下文,退出app。通过一个工具类来模拟调用Toast显示。

主界面布局activity_get_globle_context.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_get_context"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/id_btn_context"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="传入上下文"/>    <Button        android:id="@+id/id_btn_context2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="使用全局上下文"/>    <Button        android:id="@+id/id_btn_context3"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="退出"/></LinearLayout>
主界面代码

import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import com.mobile.cdtx.blog.R;import com.mobile.cdtx.blog.main.tools.DialogUtil;public class GetContextActivity extends AppCompatActivity implements View.OnClickListener{    Button btnContext,btnContext2,btnContext3;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_get_globle_context);        initView();//控件初始化    }    //控件的初始化    private void initView(){        btnContext = (Button)findViewById(R.id.id_btn_context);        btnContext.setOnClickListener(this);        btnContext2 = (Button)findViewById(R.id.id_btn_context2);        btnContext2.setOnClickListener(this);        btnContext3 = (Button)findViewById(R.id.id_btn_context3);        btnContext3.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.id_btn_context:                btnClickOne();              break;            case R.id.id_btn_context2:                btnClickTwo();                break;            case R.id.id_btn_context3:                btnExit();                break;        }    }    //传入参数    private void btnClickOne(){        DialogUtil.showToastWithContext(GetContextActivity.this,"传入了上下文");    }    //不传入参数    private void btnClickTwo(){        DialogUtil.showToastWithoutContext("使用全局上下文");    }    //退出app    private void btnExit(){        finish();    }}
测试工具类:
import android.content.Context;import android.text.TextUtils;import android.widget.Toast;import com.mobile.cdtx.blog.main.base.MyApplication;/** * Created by wangwentao on 2017/2/21. * 主要用于测试根据是否传入上下文调用弹出框 */public class DialogUtil {    //传入上下文     public static void showToastWithContext(Context context,String content){         if(context != null && !TextUtils.isEmpty(content)){             Toast.makeText(MyApplication.getContext(), content, Toast.LENGTH_SHORT).show();         }     }    //不需要传上下文    public static void showToastWithoutContext(String content){        if(!TextUtils.isEmpty(content)){            Toast.makeText(MyApplication.getContext(), content, Toast.LENGTH_SHORT).show();        }    }}
主界面效果图:

二、上下文的使用讲解

1)上下文的继承关系

从继承关系可以看出Context是一个抽象类,内部定义了多个抽象的方法;

ContextIml是Context的实现类;

ContextWrapper类是对Context的一种封装,该类的构造函数包含了一个真正的Context引用,即ContextIml对象。一般在创建Application、Service、Activity时赋值  

ContextThemeWrapper类,该类内部包含了主题(Theme)相关的接口,即android:theme属性指定的。只有Activity需要主题,Service不需要主题,所以Service直接继承于ContextWrapper类。

Activity类 、Service类 、Application类本质上都是Context子类。

2)Context的创建,主要有以下几种情况:

1、创建Application 对象时, 而且整个App共一个Application对象
2、创建Service对象时
3、创建Activity对象时

通过以上几种方式,可以得出一个结论,整个app中所有的Context的个数应该为

总Context实例个数 = Service个数 + Activity个数 + 1;

其中整个app中只有一个Application的上下文

3)上下文的使用场景

这里引用一张网上的图,可以说明情况:

关于里面的数字的函数说明:

数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task。一般情况不推荐。
数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用。
数字3:在receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视)
注:ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。

大家注意到没有,测试demo中使用了一个工具类,工具类中使用了Toast测试使用全局上下文的情况,没有问题,如果在工具类中写一个调用对话框,使用全局上下文的情况,会怎么样呢?

直接报错,有兴趣的可以直接试下。

结论就是Context不能随便乱用,当不知道怎么用时,可以参考下这张表。

4)如何获取上下文

1、this  即当前的application或activity或service。
2、getApplication()  系统提供的单例对象,每个应用只有一个。只能在activity和service(以及application类)中调用,获得应用的application单例对象。
3、getApplicationContext()  getApplicationContext()返回应用的上下文,生命周期是整个应用。相对比getApplication获取的对象是一样的,都是应用的application单例对象,但是应用范围更加广,可以例如broadcast receiver中可以使用。
4、getBaseContext()    返回由构造函数指定或setBaseContext()设置的上下文,调用该方法时获取一个ContextWrapper初始化为具体的Application、Service、ContextThemeWrapper的context。不建议使用。
5、getActivity()    在fragment中获取fragment从属的activity的context,相当于该Activity的activity.this。存在于该activity的生命周期中。
6.getContext()   返回当前这个View对象的context






0 0
原创粉丝点击