首页 > 编程知识 正文

android 路由实现原理,android移动应用基础教程课后答案

时间:2023-05-06 14:28:54 阅读:63203 作者:3631

什么是严格模式

严格模式是android在API9后引入的检测影响app运行顺畅性的机制,例如,众所周知,主线不允许网络操作的规则是一种严格的模式规则。

名为strictmode.java的类设置了许多detect标志位,如DETECT_NETWORK,并设置了许多penalty标志位,如PENALTY_NETWORK 检测标志位确定严格模式是否检测到此内容,penalty标志位是

严格模式类的一个作用是管理这些标志位,并且可以通过setThreadPolicy )方法来设置Policy变量的掩码值。

然后,POLICY变量传递给BlockGuard,BlockGuard在Dalvik虚拟机上运行,以统一管理所有异常操作。

安卓官方文档中的严格模式说明

严格模式是一种开发工具,通过引入它可以发现和修复开发中出现的问题。

应用程序主路线经常发生与UI相关的操作和动画。 严格模式允许主线程检测硬盘和与网络相关的操作。 从主线程中删除硬盘读写和网络相关操作,可以提高APP的流畅度和响应速度。 另外,为了提高app的响应性,也可以在发生ANR时阻止弹出的诊断程序。

值得注意的是,尽管android设备的许多硬盘类型是闪存存储器,但在这种存储介质上构建的文件系统的并发性仍然非常有限。 从速度上看,RAM一定更快。

在大多数情况下,硬盘读写操作非常快,但后台进程可能会执行非常大的I/O操作,这将大大降低app的响应速度。

一. setThreadPolicy ()进程

严格模式如何启动严格模式,如严格模式类文档中所述

*公共void oncreate

*if(developer_mode ) {

*严格模式. setthreadpolicy (new { @ linkthreadpolicy.builderstrictmode.thread policy.builder } ) ) ) )。

* .detectDiskReads () )

* .detectDiskWrites () )

*.detectnetwork(/or.detectall ) ) for all detectable problems

* .penaltyLog () )。

* .build ();

*严格模式. setvmpolicy (new (@ linkvmpolicy.builderstrictmode.VM policy.builder ) ) )

* .detectLeakedSqlLiteObjects ()

* .detectLeakedClosableObjects (

* .penaltyLog () )。

* .penaltyDeath () )。

* .build ();

* }

* super.onCreate (;

1.

setThreadPolicy ) )函数后,调用setThreadPolicyMask ) )方法。

公共服务语音策略(finalthreadpolicypolicy ) {

setthreadpolicymask (policy.mask;

}

2.

在setThreadPolicyMask ()方法中,除了java层threadLocal之外,还需要设定为Native层.

私有策略掩码(finalint策略掩码) {

//inadditiontothejava-level thread-localindalvik ' s

//BlockGuard,wealsoneedtokeepanativethread-localin

//binderinordertopropagatethevalueacrossbindercalls,

//evenacrossnative-only processes.thetwoarekeptin

//syncviathecallbacktoonstrictmodepolicychange,below。

setblockguardpolicy;

//And

set the Android native version...

Binder.setThreadStrictModePolicy(policyMask);

}

3.

首先分析java层的 setBlockGuardPolicy()方法.

如果policyMask==0,会返回一个默认policy,默认policy不进行任何设置和检测,policy对象存储在threadLocal变量中(每个线程保存一个policy的对象),首次运行该方法会生成一个默认policy(mMask=0)保存在threadLocal中,这里的policy对象是AndroidBlockGuardPolicy类型.

// Sets the policy in Dalvik/libcore (BlockGuard)

private static void setBlockGuardPolicy(final int policyMask) {

if (policyMask == 0) {

BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);

return;

}

final BlockGuard.Policy policy = BlockGuard.getThreadPolicy();

final AndroidBlockGuardPolicy androidPolicy;

if (policy instanceof AndroidBlockGuardPolicy) {

androidPolicy = (AndroidBlockGuardPolicy) policy;

} else {

androidPolicy = threadAndroidPolicy.get();

BlockGuard.setThreadPolicy(androidPolicy);

}

androidPolicy.setPolicyMask(policyMask);

}

4.

再看Native层的代码:

设置了policy

386void IPCThreadState::setStrictModePolicy(int32_t policy)

387{

388 mStrictModePolicy = policy;

389}

二.StrictMode如何检测问题.

1.

CloseGuard检测游标是否正常关闭:

当使用ContentResolver来查询数据库的时候,会返回一个CursorWrapperInner类型的Cursor对象.

mCursor = mResolver.query(mUri, null, null, null, null);

CloseGuard对CursorWrapperInner是否正常关闭的检测的逻辑在finalize()函数中,finalize()会在gc执行垃圾回收的时候被调用(垃圾回收使用了GcRoot算法)

如果没有执行CursorWrapperInner的close()函数,仅将CursorWrapperInner对象置为null,当主动触发gc的时候( Systemgc()),finalize()函数被调用 ,"Cursor finalized without prior close()"这段log被打印.但如果没有将CursorWrapperInner对象置为null,这时主动触发gc并不会引起 finalize()函数的执行,因为CursorWrapperInner对象被强引用,垃圾回收器在回收时不会考虑回收强引用对象,即使最后内存不足而崩溃.

经过测试程序的测试,发现"Cursor finalized without prior close()"这段log在 CursorWrapperInner对象置空并执行 System.gc()后是会打印出来的.

但是 CloseGuard中的 warnIfOpen()函数始终没有执行

在 CursorWrapperInner的构造函数中,mCloseGuard执行 open()函数,在 open函数中allocationSite被赋值,而 ENABLED 变量是默认为true的,唯一改变它的setEnabled()方法在源码中也并没有被调用,所以应该是会在REPORTER中打印SystemLog的,但最后SystemLog并没有打印,具体原因分析不出来.

@Override

protected void finalize() throws Throwable {

try {

if (mCloseGuard != null) {

mCloseGuard.warnIfOpen();

}

if (!mProviderReleased && mContentProvider != null) {

// Even though we are using CloseGuard, log this anyway so that

// application developers always see the message in the log.

Log.w(TAG, "Cursor finalized without prior close()");

ContentResolver.this.releaseProvider(mContentProvider);

}

} finally {

super.finalize();

}

}

}

public void warnIfOpen() {

if (allocationSite == null || !ENABLED) {

return;

}

String message =

("A resource was acquired at attached stack trace but never released. "

+ "See java.io.Closeable for information on avoiding resource leaks.");

REPORTER.report(message, allocationSite);

}

@Override public void report (String message, Throwable allocationSite) {

System.logW(message, allocationSite);

}

CursorWrapperInner(Cursor cursor, IContentProvider icp) {

super(cursor);

mContentProvider = icp;

mCloseGuard.open("close");

}

2.

onSqliteObjectsLeaked()也是用来检测数据库游标有没有正常关闭,但这个函数检测的是通过SqliteDataBase. query()得到的SqliteCursor游标对象.

检测位置也是在 finalize()函数中.

/**

* Release the native resources, if they haven't been released yet.

*/

@Override

protected void finalize() {

try {

// if the cursor hasn't been closed yet, close it first

if (mWindow != null) {

if (mStackTrace != null) {

String sql = mQuery.getSql();

int len = sql.length();

StrictMode.onSqliteObjectLeaked(

"Finalizing a Cursor that has not been deactivated or closed. " +

"database = " + mQuery.getDatabase().getLabel() +

", table = " + mEditTable +

", query = " + sql.substring(0, (len > 1000) ? 1000 : len),

mStackTrace);

}

close();

}

} finally {

super.finalize();

}

}

流程如下图

三.StrictMode中使用到的桥接模式

桥接模式:所谓桥接模式就是将逻辑的抽象与实现分开的一种模式

总结

以上所述是小编给大家介绍的Android StrictMode运行流程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。