Android窗口和相关页面的参考文档(例如,WindowManager.LayoutParams和Window.Callback)在很多地方引用"面板".例如,Window.Callback页面具有以下内容.
Window.Callback API从Window返回其调用者.这允许客户端拦截密钥调度,面板和菜单等.
和
public abstract查看onCreatePanelView(int featureId)
在API级别1中添加
实例化视图以在'featureId'面板中显示.您可以返回null,在这种情况下,将为您创建默认内容(通常是菜单).
参数featureId:正在创建哪个面板.
返回视图:要放置在面板中的顶级视图.
WindowManager.LayoutParams似乎将Panels视为Windows"类型",例如:
TYPE_APPLICATION_PANEL窗口类型:应用程序窗口顶部的面板.TYPE_APPLICATION_SUB_PANEL窗口类型:应用程序窗口顶部的子面板.TYPE_STATUS_BAR_PANEL窗口类型:从状态栏上滑出的面板在多用户系统中显示在所有用户的窗口上.TYPE_SYSTEM_DIALOG窗口类型:从状态栏滑出的面板在多用户系统中显示在所有用户的窗口上.
我也仔细阅读了源代码,但如果不花费数小时的时间就无法取得任何重大进展.
什么是Windows面板,如参考文档中所使用的那样?
在相关的说明中,featureId是什么?在上面的onCreatePanelView(int featureId)中,它似乎是用于指定面板的ID,但在其他上下文中,它似乎用于标识一组Windows功能,例如,用于Window.requestFeature():
public boolean requestFeature(int featureId)
在API级别1中添加
启用扩展屏幕功能.必须在setContentView()之前调用它.可以根据需要多次调用,只要它在setContentView()之前.如果未调用,则不会提供扩展功能.请求后,您无法关闭该功能.您可以使用FEATURE_CUSTOM_TITLE来使用其他标题功能.
参数featureId:所需的功能,由Window定义为常量.
返回:现在设置的功能.
谢谢,巴里
问题是,我如何获得当前的活动?已经在Stackoverflow和其他网站上被问了几十次,并且有很多提议的方法.然而,它们都具有某种形式的缺点.
在这篇文章中,我假设Android的API中没有为此提供解决方案,例如:Application.getTask().getRootActivity().
如果有:-)那不是很好吗?
所以,要清楚,我不是要求答案我如何获得当前的活动?
相反,我问的是没有提供这种能力的原因.假设每个正在运行的应用程序都有一个任务(假设任务没有被清空)并且每个这样的任务都有一个root活动,那么提供对该根Activity的访问似乎很容易.
在没有提供这种访问的情况下,当它非常明确地需要时,这对我来说意味着Android架构有一些我不理解的基础.
我错过了什么?为什么Android API不提供此信息?
作为背景,这里是一个概述已经提出的一些方法的部分.我发现以下两个链接特别有用(下面的每个方法都在一个或两个链接中提供).
链接
途径
ActivityManager
ActivityManager方法仅提供Activity类的名称,而不是当前的Activity实例.例如,对于Context实例c:
c.getSystemService().getActivityManager()
.getAppTasks().get(0).getTaskInfo()
.topActivity().getClassName()
反射
我最喜欢的是_AZ提出的反思,但这种方法很脆弱,因为它依赖于内部.我想从Android看到的是这种方法是通过标准API提供的,开发人员可以安全地依赖它.
静电钩
最常见的方法是使用静态挂钩来保存对当前运行的Activity的引用.钩子可以是按活动或按应用程序.通过保存/销毁钩子的值可以避免内存泄漏(例如,在onCreate()/ onDestroy(),onStart()/ onStop(),onPause()/ onResume()).但是,当涉及多个活动时(例如,由于生命周期重叠 - 见下文),可能会出现问题.
我实现了一个静态钩子方法,它执行以下操作(完全透明,我还没有实现#1 - 我目前正在使用per-Activity静态钩子,这是一个bug).
理论上,这将允许我始终知道任务的后台堆栈的完整状态 - 完整的活动集,包括根活动,以及它们的当前状态.然而,在实践中,有一个转折 - 当一个活动开始另一个活动时,它们的生命周期重叠.在此期间,在堆栈停止时偷看可能会产生意外的Activity实例.
来自:https://developer.android.com/guide/components/activities/activity-lifecycle.html#soafa,"协调活动":
以下是活动A启动活动B时发生的操作顺序:
- 活动A的onPause()方法执行.
- 活动B的onCreate(),onStart()和onResume()方法按顺序执行.(活动B现在具有用户关注点.)
- 然后,如果活动A在屏幕上不再可见,则执行onStop()方法
当然,这也可以管理.最重要的是,我们确实有一个可用于存储信息的全局上下文(应用程序),我们确实拥有有关活动生命周期转换的完整信息,因此我付出了足够的努力,我相信这种基于静态堆栈的方法可能会成为相当的子弹 - 证明.
不过最终
但最后我觉得我只是简单地重写代码,这些代码可能已经存在于内部,用于管理一个Activity后台堆栈,这就是为什么我要问(如果你忘记了):
为什么没有用于获取当前活动的Android API?
在这个更新中,我将总结我从这个主题以及我自己的实验和研究中学到的东西.希望这个摘要对其他人有用.
我将根据https://developer.android.com/guide/components/activities/activity-lifecycle.html上的活动状态定义,对"活动可见性状态"使用以下定义.
-----------------------------------
Visibility State Definition
----------------------------------- …Run Code Online (Sandbox Code Playgroud) 我试图让Android AVD适用于Jelly Bean(API-16)和Google API(我在平台定义中都包含了这两个).运行AVD时,我会收到以下错误.
$ emulator -avd Nexus_7_API_16_With_Google_APIs
模拟器:错误:这个AVD的配置缺少一个内核文件!模拟器:ERROR:ANDROID_SDK_ROOT已定义(C:\ data\applications\Android\Sdk)但无法在C:\ data\applications\Android\Sdk\system-images\sub目录中找到内核文件
我已经阅读了Stackoverflow和其他网站上可以找到的所有类似实例,但似乎没有一个与我的情况相关.
与大多数配置文件不同,用于Jelly Bean和Google API的配置文件似乎位于附加组件而不是系统映像中.例如:
$ cd $ ANDROID_SDK_HOME/.android/avd/Nexus_7_API_16_With_Google_APIs.avd/config.ini
$ grep image config.ini
image.sysdir.1 =插件\插件-google_apis-谷歌-16 \图像\ armeabi-V7A
实际上,"system-image"似乎被硬编码到模拟器中(尽管有可能存在一条路径 - 请参阅Android Studio中的无法运行模拟器).
这对我来说非常像一个错误.
建议???
谢谢,巴里
事实证明,adbd Insecure实际上是问题所在.当我禁用它时(通过运行应用程序并取消选中启用不安全的adbd,我能够通过wifi连接得很好.
此外,对于那些感兴趣的人,一旦这个工作,那么netstat -n确实显示了连接,即:
$ netstat -n
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN
tcp 0 0 **192.168.0.169:5555** 192.168.0.50:51178 ESTABLISHED
tcp6 0 0 ::ffff:127.0.0.1:47514 :::* LISTEN
Run Code Online (Sandbox Code Playgroud)
巴里
我无法通过Wifi连接adb(它可以通过USB工作正常).
我已经阅读了这里和其他地方的各种帖子,但没有找到适合我的答案.
我已经尝试从我的笔记本电脑连接到两个不同的设备(三星S4,Nexus 7 2013(wifi)它在两种情况下均无法连接,但具有相同的错误消息,尽管具有特定设备的IP地址,例如:
无法连接到192.168.0.125:5555
这两款设备都采用了毛巾,SuperSU和"adbd Insecure".我可以从我的笔记本电脑ping 192.168.0.125,我已经关闭了我的笔记本电脑的病毒防护和防火墙.
我按照标准步骤:
我读到"netstat -n"应该显示一个新的套接字存在并监听端口5555(无法通过ADB通过ADB连接到Android - 我是否需要root访问权限?)但在我的情况下不会发生 - 它仅显示默认端口5037的localhost连接.
root@deb:/ # netstat -n
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp …Run Code Online (Sandbox Code Playgroud) 我想vi在跑步时使用adb shell。启动“vi”很容易。但是,我发现按键ESC似乎无法接通,因此无法退出插入模式。
更广泛地说,我似乎根本无法将字符发送ESC到 adb shell。我已经彻底扫描了网络,但找不到任何有类似问题的人(更不用说答案)。
我在 Samsung S4 上运行 VRUFNK1。在 PC 端,我在 Windows 下从 Cygwin 运行“adb shell”命令。
\n\n想法???
\n\n更新:这里有一些可能的线索。
\n\nod -cb > file,因此 ESC 似乎正在访问 adb shell 下运行的程序。与 #1 类似,bash (Bash X) 似乎收到了它,尽管 bash 的回显很奇怪。我可以使用 ESC 在 bash shell …
我已经阅读了标准的Windows相关文档,并通过一堆源代码,试图了解如何以及何时创建Android Windows.我相信我搂着它,并希望得到验证或纠正.
据我所知,只有两种方法来获取Window对象的句柄.
1. Activity's getWindow.
2. Dialog's getWindow method.
Run Code Online (Sandbox Code Playgroud)
在上述两种情况下,您都可以使用getWindow获取Window的句柄,然后使用句柄操作Window.
Windows也可以通过使用WindowManager的addView方法创建,但是无法获得此类Windows的句柄.这是一个非常令人困惑的区域,因为addView方法本身并不意味着创建一个Window,甚至在View Manager源代码中对它的注释只是说明如下.
Assign the passed LayoutParams to the passed View and add the view to
the window.
Run Code Online (Sandbox Code Playgroud)
因此,该方法似乎意味着将View添加到现有Window.但是,addView的第二个参数是一个WindowManager.LayoutParams实例,除其他外,它指定一个Window类型(例如,TYPE_SYSTEM_ALERT),暗示实际上正在创建一个Window.事实上,情况就是如此.以下是源代码中发生的事情的简要概述.(对于新手:您可以在许多不同的网站上浏览源代码;我最喜欢的是http://grepcode.com.)
WindowManager实现了ViewManager接口,这是定义addView的地方.网址:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/ViewManager.java#ViewManager.addView%28android.view.查看%2Candroid.view.ViewGroup.LayoutParams 29%
WindowManager类的实际实现称为WindowManagerImpl.它的addView调用WindowManagerGlobal的addView.网址:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/WindowManagerImpl.java#83
WindowManagerGlobal的addView是真正完成工作的地方.网址:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/WindowManagerGlobal.java#WindowManagerGlobal.addView%28android.view.查看%2Candroid.view.ViewGroup.LayoutParams%2Candroid.view.Display%2Candroid.view.Window 29%
ViewRootImpl的setView方法然后做了一堆低级工作.它会在各种错误情况下抛出"无法添加窗口..."消息的变体异常.根据ViewRootImpl的主要评论,它是"视图层次结构的顶层,在View和WindowManager之间实现所需的协议.这在很大程度上是WindowManagerGlobal的内部实现细节."
网址:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/ViewRootImpl.java#ViewRootImpl.setView%28android.view.查看%2Candroid.view.WindowManager.LayoutParams%2Candroid.view.View 29%
WindowManagerGlobal似乎通过三个阵列跟踪多个Windows.据我所知,ViewRootImpl实际上是新窗口,它由WindowManagerGlobal管理.
基于以上所述,看来调用addView实际上创建了一个新窗口(尽管它被不同地称为视图和窗口)但是没有提供相关的Window类来访问它,因此开发人员不能得到它的句柄.
我的问题是:
谢谢!巴里