想了解如何在非活动类(LocationManager)中使用getSystemService?的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于非活动应用程序加载项怎么启用的相关问题,此外,我
想了解如何在非活动类 (LocationManager) 中使用 getSystemService?的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于非活动应用程序加载项怎么启用的相关问题,此外,我们还将为您介绍关于.NET Core,Windows Nano Server和System.Management.Automation、Android getSystemService()、android servicemanager与binder源码分析一 ------ native层的ServiceManager、android – getLayoutInflator和(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)之间的区别是什么的新知识。
本文目录一览:- 如何在非活动类 (LocationManager) 中使用 getSystemService?(非活动应用程序加载项怎么启用)
- .NET Core,Windows Nano Server和System.Management.Automation
- Android getSystemService()
- android servicemanager与binder源码分析一 ------ native层的ServiceManager
- android – getLayoutInflator和(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)之间的区别是什么
如何在非活动类 (LocationManager) 中使用 getSystemService?(非活动应用程序加载项怎么启用)
我无法将主要活动 OnCreate 方法中的任务卸载到另一个类来完成繁重的工作。
当我尝试从非 Activity 类调用 getSystemService 时,会引发异常。
任何帮助将不胜感激 :)
lmt.java:
package com.atClass.lmt;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.location.Location;
public class lmt extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
fyl lfyl = new fyl();
Location location = lfyl.getLocation();
String latLongString = lfyl.updateWithNewLocation(location);
TextView myLocationText = (TextView)findViewById(R.id.myLocationText);
myLocationText.setText("Your current position is:\n" + latLongString);
}
}
fyl.java
package com.atClass.lmt;
import android.app.Activity;
import android.os.Bundle;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;
import android.content.Context;
public class fyl {
public Location getLocation(){
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
return location;
}
public String updateWithNewLocation(Location location) {
String latLongString;
if (location != null){
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
}else{
latLongString = "No Location";
}
return latLongString;
}
}
.NET Core,Windows Nano Server和System.Management.Automation
核心中包含的.NET库列于here.有些是完整的,有些则不是.但我不明白的是,列表中缺少System.Management.Automation.
此库是用于在.NET应用程序中使用PowerShell cmdlet的库.考虑到PowerShell今天对系统管理员的重要性,根据Nano Server的这种省略似乎很奇怪.
这是否意味着System.Management提供的功能.Automation在Windows Nano Server中不可用?
解决方法
从下载的包中引用dll,您应该能够运行powershell命令.
Android getSystemService()
使用getSystemService()获取系统服务,需要注意的是,总是使用上下文
context.getSystemService
来调用该方法,如获取网络状态的服务
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); State mobile = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState(); State wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState(); // 如果3G、WIFI、2G等网络状态是连接的,则退出,否则显示提示信息进入网络设置界面 if (mobile == State.CONNECTED || mobile == State.CONNECTING) return true; if (wifi == State.CONNECTED || wifi == State.CONNECTING) return true;
文档解释:
Note: System services obtained via this API may be closely associated with the Context in which they are obtained from.
In general, do not share the service objects between varIoUs different contexts (Activities, Applications, Services, Providers, etc.)
转载于:https://www.cnblogs.com/xl0715/p/3438109.html
android servicemanager与binder源码分析一 ------ native层的ServiceManager
前一阵子在忙项目,没什么更新,这次开始写点android源码内部的东西分析下。以6.0.1_r10版本android源码为例。
servicemanager是android服务管理,非常基础的组件之一,分析他的目的是能够深入看到binder的一些处理方式。在开始前先说下阅读源码或者非常复杂代码的方式,我的方式是层级进入,一层掌握脉络之后如果感兴趣再对具体的点深入分析了解,并且每层进行总结,这样我认为会比较好理解,也不容易产生一个点一直走下去,最后迷失在复杂繁琐的代码里的情况。当然我只代表我个人的体验。东西是写给自己的,如果能帮到他人我会非常高兴。
然后这里推荐下罗升阳先生的博客文章,确实非常不错,可以作为阅读参考。
servicemanager源码位于/frameworks/native/cmds/servicemanager/service_manager.c下:
347int main(int argc, char **argv)
348{
349 struct binder_state *bs;
350
351 bs = binder_open(128*1024);
352 if (!bs) {
353 ALOGE("failed to open binder driver\n");
354 return -1;
355 }
356
357 if (binder_become_context_manager(bs)) {
358 ALOGE("cannot become context manager (%s)\n", strerror(errno));
359 return -1;
360 }
361
362 selinux_enabled = is_selinux_enabled();
363 sehandle = selinux_android_service_context_handle();
364 selinux_status_open(true);
365
366 if (selinux_enabled > 0) {
367 if (sehandle == NULL) {
368 ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
369 abort();
370 }
371
372 if (getcon(&service_manager_context) != 0) {
373 ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
374 abort();
375 }
376 }
377
378 union selinux_callback cb;
379 cb.func_audit = audit_callback;
380 selinux_set_callback(SELINUX_CB_AUDIT, cb);
381 cb.func_log = selinux_log_callback;
382 selinux_set_callback(SELINUX_CB_LOG, cb);
383
384 binder_loop(bs, svcmgr_handler);
385
386 return 0;
387}
1.binder_open打开binder驱动设备;
2.binder_become_context_manager(bs),将自己作为binder的管理者;
3.binder_loop(bs, svcmgr_handler),进入循环,作为server等待client的请求;
binder_open
位于/frameworks/native/cmds/servicemanager/binder.c:
96struct binder_state *binder_open(size_t mapsize)
97{
98 struct binder_state *bs;
99 struct binder_version vers;
100
101 bs = malloc(sizeof(*bs));
102 if (!bs) {
103 errno = ENOMEM;
104 return NULL;
105 }
106
107 bs->fd = open("/dev/binder", O_RDWR);
108 if (bs->fd < 0) {
109 fprintf(stderr,"binder: cannot open device (%s)\n",
110 strerror(errno));
111 goto fail_open;
112 }
113
114 if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
115 (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
116 fprintf(stderr,
117 "binder: kernel driver version (%d) differs from user space version (%d)\n",
118 vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
119 goto fail_open;
120 }
121
122 bs->mapsize = mapsize;
123 bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
124 if (bs->mapped == MAP_FAILED) {
125 fprintf(stderr,"binder: cannot map device (%s)\n",
126 strerror(errno));
127 goto fail_map;
128 }
129
130 return bs;
131
132fail_map:
133 close(bs->fd);
134fail_open:
135 free(bs);
136 return NULL;
137}
首先,建立一个结构体binder_state,然后剩下的就是给这个结构体的成员赋值。bs->fd给打开的驱动设备文件描述符;bs->mapped给内存映射地址;
插一句,这里对goto的应用很规范,可见任何语句并非有好与不好,而在于怎么用。
看到这里其实可以猜测,binder的机制就是内存映射,或者可以说是文件映射,因为在linux上任何的设备都可以看做是文件。
现在不要深入,往回看,之前的service_manager.c的main函数里,后面就要走binder_become_context_manager这个将自己设为binder管理者。
146int binder_become_context_manager(struct binder_state *bs)
147{
148 return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
149}
这里就做了一件事儿,就是下发控制字,告诉驱动设置context管理者为0,这里也可以猜测,这个0代表一定含义,应该就是servicemanager自己,后面再继续解释这个问题。
binder_looper
372void binder_loop(struct binder_state *bs, binder_handler func)
373{
374 int res;
375 struct binder_write_read bwr;
376 uint32_t readbuf[32];
377
378 bwr.write_size = 0;
379 bwr.write_consumed = 0;
380 bwr.write_buffer = 0;
381
382 readbuf[0] = BC_ENTER_LOOPER;
383 binder_write(bs, readbuf, sizeof(uint32_t));
384
385 for (;;) {
386 bwr.read_size = sizeof(readbuf);
387 bwr.read_consumed = 0;
388 bwr.read_buffer = (uintptr_t) readbuf;
389
390 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
391
392 if (res < 0) {
393 ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
394 break;
395 }
396
397 res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
398 if (res == 0) {
399 ALOGE("binder_loop: unexpected reply?!\n");
400 break;
401 }
402 if (res < 0) {
403 ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
404 break;
405 }
406 }
1.先通过binder_write下发了一个BC_ENTER_LOOPER控制字,表示要驱动设备进入looper状态(binder_write内部也是走的ioctrl BINDER_WRITE_READ写入驱动设备);
2.进入死循环,不停从设备读取数据,成功读取到之后,进入binder_parse函数;
3.binder_parse,从字面看是解析binder,但是具体做什么不清楚,只能猜测是对刚才读取到的内容进行处理。
同属于binder.c这一层,因此我们看看binder_parse具体内容:
204int binder_parse(struct binder_state *bs, struct binder_io *bio,
205 uintptr_t ptr, size_t size, binder_handler func)
206{
207 int r = 1;
208 uintptr_t end = ptr + (uintptr_t) size;
209
210 while (ptr < end) {
211 uint32_t cmd = *(uint32_t *) ptr;
212 ptr += sizeof(uint32_t);
213#if TRACE
214 fprintf(stderr,"%s:\n", cmd_name(cmd));
215#endif
216 switch(cmd) {
217 case BR_NOOP:
218 break;
219 case BR_TRANSACTION_COMPLETE:
220 break;
221 case BR_INCREFS:
222 case BR_ACQUIRE:
223 case BR_RELEASE:
224 case BR_DECREFS:
225#if TRACE
226 fprintf(stderr," %p, %p\n", (void *)ptr, (void *)(ptr + sizeof(void *)));
227#endif
228 ptr += sizeof(struct binder_ptr_cookie);
229 break;
230 case BR_TRANSACTION: {
231 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
232 if ((end - ptr) < sizeof(*txn)) {
233 ALOGE("parse: txn too small!\n");
234 return -1;
235 }
236 binder_dump_txn(txn);
237 if (func) {
238 unsigned rdata[256/4];
239 struct binder_io msg;
240 struct binder_io reply;
241 int res;
242
243 bio_init(&reply, rdata, sizeof(rdata), 4);
244 bio_init_from_txn(&msg, txn);
245 res = func(bs, txn, &msg, &reply);
246 binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
247 }
248 ptr += sizeof(*txn);
249 break;
250 }
251 case BR_REPLY: {
252 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
253 if ((end - ptr) < sizeof(*txn)) {
254 ALOGE("parse: reply too small!\n");
255 return -1;
256 }
257 binder_dump_txn(txn);
258 if (bio) {
259 bio_init_from_txn(bio, txn);
260 bio = 0;
261 } else {
262 /* todo FREE BUFFER */
263 }
264 ptr += sizeof(*txn);
265 r = 0;
266 break;
267 }
268 case BR_DEAD_BINDER: {
269 struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;
270 ptr += sizeof(binder_uintptr_t);
271 death->func(bs, death->ptr);
272 break;
273 }
274 case BR_FAILED_REPLY:
275 r = -1;
276 break;
277 case BR_DEAD_REPLY:
278 r = -1;
279 break;
280 default:
281 ALOGE("parse: OOPS %d\n", cmd);
282 return -1;
283 }
284 }
285
286 return r;
287}
刚才从驱动设备读取的buffer的前32位取出来作为cmd进行switch判断处理。BR_代表从设备驱动反馈的命令,BR_TRANSACTION字面看是交易,那么可以猜测是对接受到的发送方(client)的内容进行处理。往下看,BR_TRANSACTION流程里,先把收到的数据转成binder_transaction_data结构,然后走了binder_dump_txn,这里基本上就是输出一些信息,不太关注。之后是关键的部分,调用了func,这个东西是个binder_handler,其实看看定义就知道,是个回调函数,回到servicemanager里面的main,可以看到是个svcmgr_handler,具体内容也在servicemanager里面,如下:
244int svcmgr_handler(struct binder_state *bs,
245 struct binder_transaction_data *txn,
246 struct binder_io *msg,
247 struct binder_io *reply)
248{
249 struct svcinfo *si;
250 uint16_t *s;
251 size_t len;
252 uint32_t handle;
253 uint32_t strict_policy;
254 int allow_isolated;
255
256 //ALOGI("target=%p code=%d pid=%d uid=%d\n",
257 // (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
258
259 if (txn->target.ptr != BINDER_SERVICE_MANAGER)
260 return -1;
261
262 if (txn->code == PING_TRANSACTION)
263 return 0;
264
265 // Equivalent to Parcel::enforceInterface(), reading the RPC
266 // header with the strict mode policy mask and the interface name.
267 // Note that we ignore the strict_policy and don''t propagate it
268 // further (since we do no outbound RPCs anyway).
269 strict_policy = bio_get_uint32(msg);
270 s = bio_get_string16(msg, &len);
271 if (s == NULL) {
272 return -1;
273 }
274
275 if ((len != (sizeof(svcmgr_id) / 2)) ||
276 memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
277 fprintf(stderr,"invalid id %s\n", str8(s, len));
278 return -1;
279 }
280
281 if (sehandle && selinux_status_updated() > 0) {
282 struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
283 if (tmp_sehandle) {
284 selabel_close(sehandle);
285 sehandle = tmp_sehandle;
286 }
287 }
288
289 switch(txn->code) {
290 case SVC_MGR_GET_SERVICE:
291 case SVC_MGR_CHECK_SERVICE:
292 s = bio_get_string16(msg, &len);
293 if (s == NULL) {
294 return -1;
295 }
296 handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
297 if (!handle)
298 break;
299 bio_put_ref(reply, handle);
300 return 0;
301
302 case SVC_MGR_ADD_SERVICE:
303 s = bio_get_string16(msg, &len);
304 if (s == NULL) {
305 return -1;
306 }
307 handle = bio_get_ref(msg);
308 allow_isolated = bio_get_uint32(msg) ? 1 : 0;
309 if (do_add_service(bs, s, len, handle, txn->sender_euid,
310 allow_isolated, txn->sender_pid))
311 return -1;
312 break;
313
314 case SVC_MGR_LIST_SERVICES: {
315 uint32_t n = bio_get_uint32(msg);
316
317 if (!svc_can_list(txn->sender_pid)) {
318 ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
319 txn->sender_euid);
320 return -1;
321 }
322 si = svclist;
323 while ((n-- > 0) && si)
324 si = si->next;
325 if (si) {
326 bio_put_string16(reply, si->name);
327 return 0;
328 }
329 return -1;
330 }
331 default:
332 ALOGE("unknown code %d\n", txn->code);
333 return -1;
334 }
335
336 bio_put_uint32(reply, 0);
337 return 0;
338}
简单看下,就是对传递的数据的具体处理,包括了addservice等具体的过程处理。暂时先不深究。
至此我们可以看出来,servicemanager->binder.c这层基本上就是servicemanager提供系统的服务管理,binder.c提供对驱动设备的操作api。整个过程再梳理下:
1.打开binder驱动设备;
2.将自己作为binder上下文的管理者,通过binder.c传递0给设备驱动(ioctrl);
3.进入binder_looper循环,不停从binder设备驱动读取内容,并解析,然后根据cmd判断后抛给servicemanager进行真正处理;
4.servicemanager里再根据读取到的数据内容来决定进行各种cmd动作的处理,包括addservice等;
这么看这一层的脉络基本上比较清晰了。这么写把binder独立了出来作为一个api层,可以搭载任何的生成调用,也就是说binder.c这一层只管与binder设备驱动通讯,其余的抛给调用者,很标准聪明的解耦。
android – getLayoutInflator和(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)之间的区别是什么
有什么区别,什么时候可以使用每一个?
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflater.inflate(R.layout.activity_custom_lists1,parent);
和
View v = getLayoutInflater().inflater.inflate(R.layout.activity_custom_lists1,parent);
解决方法
View v = getLayoutInflater().inflater.inflate(R.layout.activity_custom_lists1,parent);
有可能
View v = getLayoutInflater().inflate(R.layout.activity_custom_lists1,parent);
second one is called for the activity scope and the first one can be called from outside the Activity with the context
今天的关于如何在非活动类 (LocationManager) 中使用 getSystemService?和非活动应用程序加载项怎么启用的分享已经结束,谢谢您的关注,如果想了解更多关于.NET Core,Windows Nano Server和System.Management.Automation、Android getSystemService()、android servicemanager与binder源码分析一 ------ native层的ServiceManager、android – getLayoutInflator和(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)之间的区别是什么的相关知识,请在本站进行查询。
本文标签: