关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android工具箱之Context解析

    Android工具箱之Context解析

    2016-01-13 00:00:00 出处:philo.top
    分享

    这几天一直在思考一个问题,为什么国内的热门博客和热门教程都是很久之前的,例如我向学习EventBus,不论是鸿洋的博文还是其他论坛,几乎清一色的OnEvent,或者比如我想学习Dagger2,文章数量更是少之又少,关键大量还是Dagger1的内容。

    基于此,外加上看到CodePath公司整合的Android资源正好符合实际需求,所以特意在sg开辟专栏,希望大家能够喜欢,在此申明下,因为工作量巨大,我非常有幸能够同@xixicat一起翻译这一专题,也恳请大家,如遇到任何翻译错误,请指正,可评论中注明,也可电邮我,同时假如某位志趣相投人士有兴趣参与翻译,也可电邮我,我会进一步联系你:neuyuandaima@gmail.com。

    废话不多说,那么我们就开始吧。

    动机

    你有多少次在StackOverflow中寻找答案时,发现其答案竟然是2年前的,你又有多少次搜出的博文是几年前的旧文呢,我相信绝大部分的你都有这样的经历,所以我们为什么不能利用社交让我们的的Android文档布满每个细节呢。

    初篇之Context初探

    概述

    Context对象可以获取应用状态的信息,其使得activitys和Fragments以及Services能够使用资源文件,图片,主题,以及其他的文件夹内容。其也可以用于使用Android自带服务,例如inflate,键盘,以及content providers。

    很多情况下,当你需要用到Context的时候,你肯定只是简单的利用当前activity的实例this。当你一个被activity创建的内部对象的时候,例如adapters里或者fragments里的时候,你需要将activity的实例传给它们。而当你在activity之外,例如application或者service的时候,我们需要利用application的context对象代替。

    Contex的用途

    明确地启动一个组件,例如activity或者service

    Intent intent = new Intent(context, MyActivity.class);
    startActivity(intent);

    创建视图

    TextView textView = new TextView(context);

    Contexts包含了以下信息:

    设备的屏幕大小以及将dp,sp转化为px的尺寸。 style属性 onClick属性

    inflate xml布局文件

    我们使用context来获得LayoutInflater,其可以在内存中inflate xml布局文件

    LayoutInflater inflater = LayoutInflater.from(context);
    inflater.inflate(R.layout.my_layout, parent);

    发送本地广播

    我们使用context来获得LocalBroadcastManager,其可以发送或者注册广播接收。

    Intent broadcastIntent = new Intent("custom-action");
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

    获取系统服务

    例如当你需要发送通知,你需要NotificationManager。

    NotificationManager manager = 
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    
    int notificationId = 1;
    
    // Context is required to construct RemoteViews
    Notification.Builder builder = 
        new Notification.Builder(context).setContentTitle("custom title");
    
    notificationManager.notify(notificationId, builder.build());

    在此就不一一列举系统服务了, 系统服务列表 参见。

    应用级别的Context和Activity级别的Context

    当主题被运用在应用层面,其也可被运用在activity层面,比如当应用层面定义了一些主题,activity可以将其覆盖。

    <application
           android:allowBackup="true"
           android:icon="@mipmap/ic_launcher"
           android:label="@string/app_name"
           android:theme="@style/AppTheme" >
           <activity
               android:name=".MainActivity"
               android:label="@string/app_name"
               android:theme="@style/MyCustomTheme">

    大部分视图需要传入activity级别的Context对象,这样其才能获取主题,styles,dimensions等属性。假如某个控件没有使用theme,其默认使用了应用的主题。

    在大部分情况下,你需要使用activity级别的Context。通常,关键字this代表着一个类的实例,其可被用于activity中的Context传递。例如:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);  
            Toast.makeText(this, "hello", Toast.LENGTH_SHORT).show();
        }
    }

    匿名方法

    当我们使用了匿名内部类的适合,例如实现监听,this关键字的使用:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            TextView tvTest = (TextView) findViewById(R.id.abc);
            tvTest.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();
                  }
              });
            }
        }

    适配器

    数组适配器

    当你为listview定义适配器的适合,getContext()方法被经常使用,其用来实例化xml布局。

    if (convertView == null) {
          convertView = 
              LayoutInflater
                  .from(getContext())
                  .inflate(R.layout.item_user, parent, false);
       }

    注意:当你传入的是应用级别的context,你会发现themes/styles属性将不会被应用,所以确保你在这里传入的是Activity级别的context。

    RecyclerView适配器

    public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
    
        @Override 
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = 
                LayoutInflater
                    .from(parent.getContext())
                    .inflate(itemLayout, parent, false);
    
            return new ViewHolder(v);
        }
    
        @Override
        public void onBindViewHolder(ViewHolder viewHolder, int i) {
            // If a context is needed, it can be retrieved 
            // from the ViewHolder's root view.
            Context context = viewHolder.itemView.getContext();
    
            // Dynamically add a view using the context provided.
            if(i == 0) {
                TextView tvMessage = new TextView(context);
                tvMessage.setText("Only displayed for the first item.")
    
                viewHolder.customViewGroup.addView(tvMessage);
            }
        }
    
       public static class ViewHolder extends RecyclerView.ViewHolder {
           public FrameLayout customViewGroup;
    
           public ViewHolder(view imageView) {
               super(imageView);
    
               // Perform other view lookups.
               customViewGroup = (FrameLayout) imageView.findById(R.id.customViewGroup);
           }
       }
    }

    可以看到,ArrayAdapter需要在其构造器里面传入context,RecyclerView.Adapter不需要。

    RecyclerView通常将其作为父视图传给RecyclerView.Adapter.onCreateViewHolder()。

    假如在onCreateViewHolder()方法的外面,你需要用到context,你也可以使用ViewHolder,例如viewHolder.itemView.getContext()。itemView是一个公有,非空,final类型的成员变量。

    避免内存泄露

    应用级别的context通常在单例中使用,例如一个常用的管理类,其管理Context对象来获取系统服务,但是其不能同时被多个activity获取。由于维护一个activity级别的context引用会导致内存泄露,所以你需要使用application级别的context替代。

    在下面这个例子中,假如context是activity级别或者service级别,当其被destroy,其实际不会被gc, 因为CustomManager类拥有了其static应用。

    pubic class CustomManager {
        private static CustomManager sInstance;
    
        public static CustomManager getInstance(Context context) {
            if (sInstance == null) {
    
                // This class will hold a reference to the context
                // until it's unloaded. The context could be an Activity or Service.
                sInstance = new CustomManager(context);
            }
    
            return sInstance;
        }
    
        private Context mContext;
    
        private CustomManager(Context context) {
            mContext = context;
        }
    }

    适当地存储context:利用应用级别context

    为了避免内存泄露,不要在其生命周期以外持有该对象。检查你的非主线程,pending handlers或者内部类是否持有context对象。

    存储应用级别的context的最好的办法是CustomManager.getInstance(),其为单例,生命周期为整个应用的进程。

    public static CustomManager getInstance(Context context) {
        if (sInstance == null) {
    
            // When storing a reference to a context, use the application context.
            // Never store the context itself, which could be a component.
            sInstance = new CustomManager(context.getApplicationContext());
        }
    
        return sInstance;
    }

    参考

    What is a context – Simple Code Stuffs Context, what context – Possible Mobile Context: What, where, & how – 101 Apps What is a context – Stack Overflow Avoiding memory leaks
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。