安卓-获取全局上下文

一、实现获取全局上下文

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

比如说封装一个工具类,工具类中需要用到上下文,可以通过参数传进去,也可以在工具类中使用全局上下文。以获取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






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值