根据context得到包名及主Activity

本文介绍如何在Android应用中通过Intent和PackageManager获取主Activity的类名以及应用的包名。具体步骤包括创建Intent、设置包名、添加类别并解析活动等。

得到主Activity:

代码如下:
          Intent it = new Intent(Intent.ACTION_MAIN);
           it.setPackage(pkg);//pkg为包名
           it.addCategory(Intent.CATEGORY_LAUNCHER);
           ComponentName ac = it.resolveActivity(mPackageManager);//mPackageManager为PackageManager实例
           String classname =ac.getClassName() ;
说明:resolveActivity()方法默认使用MATCH_DEFAULT_ONLY的flag ,是指activity中的catetory必须要包含android.intent.category.DEFAULT类型,否则会返回null。这时可以用 PackageManager 的getLaunchIntentForPackage()方法直接获取intent,再通过intent的getcomonent().getClassName()获取类名,另外getLaunchIntentForPackage() 是PackageManager 的一个抽象方法,其实现是在ApplicationPackageManager包内。

得到包名:

con.getApplicationInfo().packageName

 

参考:

http://www.eoeandroid.com/thread-179197-1-1.html
<think>我们正在讨论LayoutInflater.from(context)中传入的Context类型(Activity或Application)的区别。 根据引用[1]和[2]的内容,我们知道虽然LayoutInflater.from(context)内部都是通过context.getSystemService()获取服务,但是当传入的是Activity时,由于Activity的getSystemService方法被重写,会创建一个与当前Activity题相关的LayoutInflater实例。而传入Application时,由于Application没有重写该方法,使用的是基类Context的实现,因此得到的LayoutInflater实例不包含题信息。 具体来说: 1. 在Activity中,我们通常会使用Activity本身作为Context,这样inflate出来的视图会带有Activity题属性(如颜色、字体等)。 2. 如果使用Application作为Context,那么inflate出来的视图将不会应用任何题(使用系统默认题),因为Application没有题信息。 因此,在需要题一致性的UI部分(例如加载一个对话框的布局、一个列表项等)应该使用Activity作为Context,以确保题正确应用。 另外,引用[4]提到View.inflate方法内部也是调用LayoutInflater.from(context)来实现的,所以同样遵循上述规则。 下面详细说明:</think>### `LayoutInflater.from(context)` 中 `Context` 与 `Activity` 的关系及使用区别 #### 一、核心关系图解 ```mermaid graph TD A[Context] --> B[Application Context] A --> C[Activity Context] C --> D[重写 getSystemService] D --> E[创建带题的 LayoutInflater] B --> F[基础系统服务] F --> G[无题的 LayoutInflater] ``` #### 二、关键区别解析 | **特性** | **Activity Context** | **Application Context** | |------------------|----------------------------------------------|---------------------------------------| | **题支持** | ✅ 继承 Activity 题属性(颜色/字体等)[^1] | ❌ 无题(使用系统默认) | | **创建机制** | 通过 `cloneInContext()` 克隆带题的实例[^1] | 直接返回基础系统服务[^2] | | **内存泄漏风险** | 可能(若持有 Activity 引用) | 安全(与应用生命周期一致) | | **典型使用场景** | UI 相关操作(对话框/自定义视图) | 后台线程/非 UI 操作 | #### 三、底层机制解析 1. **`Activity Context` 特殊处理** 当传入 Activity 时,触发其重写的 `getSystemService()`: ```java // ContextThemeWrapper.java public Object getSystemService(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { // 关键步骤:创建带题的实例 mInflater = LayoutInflater.from(getBaseContext()) .cloneInContext(this); } return mInflater; } return getBaseContext().getSystemService(name); } ``` 此操作将题信息注入 `LayoutInflater`[^1]。 2. **`Application Context` 基础实现** 直接调用系统服务,无题注入: ```java // LayoutInflater.from() 源码 public static LayoutInflater from(Context context) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (inflater == null) throw new AssertionError(); return inflater; // 直接返回基础实例 } ``` #### 四、正确使用场景 ##### 1. 必须使用 `Activity Context` 的情况 ```java // 对话框必须使用 Activity Context AlertDialog.Builder builder = new AlertDialog.Builder(activityContext); // 自定义 View 组件(需题一致) public class CustomView extends LinearLayout { public CustomView(Context context) { super(context); LayoutInflater.from(context).inflate( R.layout.custom_view, this, true ); } } ``` > ✅ **原因**:确保题属性(如 `?attr/colorPrimary`)正确解析[^1] ##### 2. 可使用 `Application Context` 的情况 ```java // 后台线程加载布局(不涉及UI渲染) new Thread(() -> { LayoutInflater inflater = LayoutInflater.from(getApplicationContext()); View view = inflater.inflate(R.layout.notification_layout, null); // ... 非UI操作 }).start(); ``` > ✅ **原因**:避免持有 Activity 引用导致内存泄漏 #### 五、题差异实例 假设 XML 布局中使用题属性: ```xml <TextView android:textColor="?attr/colorPrimary" /> ``` - **使用 Activity Context**: ➡️ 显示为当前 Activity题色(如蓝色) - **使用 Application Context**: ➡️ 显示为系统默认色(通常黑色) #### 六、最佳实践原则 1. **UI 操作必用 Activity Context** 确保题一致性,特别是在 `Adapter`、`Fragment` 中: ```java // RecyclerView.Adapter 示例 View onCreateViewHolder(ViewGroup parent, int type) { return LayoutInflater.from(parent.getContext()) // 自动获取 Activity Context .inflate(R.layout.list_item, parent, false); } ``` 2. **避免交叉使用** 不要混用两种 Context: ```java // 危险操作:可能题错乱 View view = LayoutInflater.from(applicationContext) .inflate(R.layout.dialog, activityRoot, false); ``` 3. **内存泄漏防护** 在静态类/后台线程中优先使用 Application Context: ```java public static void safeInflate(Context appContext) { // 使用 Application Context LayoutInflater.from(appContext.getApplicationContext()); } ``` > 总结:`LayoutInflater.from(context)` 的行为取决于 `Context` 类型。**Activity Context 注入题信息,适合 UI 操作;Application Context 提供基础服务,适合非 UI 场景**。错误选择会导致题异常或内存泄漏[^1][^2]。 --- ### 相关问题 1. **为什么在自定义 View 的构造函数中必须使用 `Activity Context`?** [答案:自定义 View 需要解析题属性,Application Context 无法提供题信息[^1]。] 2. **如何在 `Service` 中正确使用 `LayoutInflater`?** [答案:若需题支持应传递 Activity Context,否则用 `getApplicationContext()`[^2]。] 3. **`LayoutInflater.cloneInContext()` 方法有什么作用?** [答案:创建携带新 Context(含题)的 LayoutInflater 副本,用于题切换场景[^1]。] 4. **使用 Application Context 加载布局会导致崩溃吗?** [答案:不会崩溃,但可能导致题属性解析失败(如 `?attr/` 开头的资源)[^1][^2]。]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值