封装对象中的运行时权限 - 如何正确处理?
Runtime permissions in capsulated objects - how to handle properly?
我想知道,如何处理封装对象中的运行时权限。
所以,假设我们有一个需要写入磁盘的记录器对象。
对象唯一应该做的就是写入磁盘。
这个对象也应该处理运行时权限吗?
对象是否一开始就不能写(通过标志),如果我们获得许可,标志将交换?
我很高兴知道你们中的一些人是如何做到这一点的。
谢谢!
权限是针对整个应用授予的,而不是针对单个对象。
如果您的应用获得一次权限,则无需再次请求。
在您的情况下,您可以在写入文件之前甚至在创建对象之前检查并请求必要的权限。
最佳做法是在使用需要权限的功能之前在上下文中请求权限。
检查我的图书馆以轻松处理权限。只需获取上下文参考,您就可以从任何地方请求权限。
您的问题没有一个明确的答案。您的问题通常与软件架构有关。所以可能会有很多不同的意见。我的给你。
通常,您希望 class 只负责一项工作。因此,记录器只记录消息,但不太关心权限。
所以我想说这通常是关于如何设计 API 并使其易于使用的问题。
例如,假设我们有一个 Logger 接口:
interface Logger {
void d(String tag, String message);
}
然后我们介绍一个具体的实现叫FileLogger
:
final class FileLogger implements Logger {
@Override
public void d(String tag, String message) {
// write a message to a file somehow
}
}
这里的问题是,如果尚未授予权限,是否应该 FileLogger#d
失败并返回 SecurityException
?或者它应该以某种方式警告开发人员?
就个人而言,在这种情况下,我会修改 FileLogger
以在尚未授予权限时不失败,但必须在应用程序的另一部分授予权限本身。
final class FileLogger implements Logger {
@Override
public void d(String tag, String messsage) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// write a log to a file
}
}
}
我们再来看一个例子。假设我们有一个名为 LocationApi
:
的接口
interface LocationApi {
@Nullable
Location getLastLocation();
}
用户必须向应用程序授予权限,这样它才能获得他最后的位置。如果应用程序没有权限,立即失败是否很关键?我会说是的!
这个接口的实现看起来像这样:
final class LocationApiImpl implements LocationApi {
@Nullable
public Location getLastLocation() {
if (ContextCompat.checkSelfPermission(..) != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException();
}
// obtain a location
}
}
P.S。有一个特殊的注释 RequiresPermission 可以帮助您指示某个方法需要权限,否则它可能会抛出 SecurityException
.
然后我们可以这样修改LocationApi
界面:
interface LocationApi {
@RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
@Nullable
Location getLastLocation();
}
我想知道,如何处理封装对象中的运行时权限。
所以,假设我们有一个需要写入磁盘的记录器对象。 对象唯一应该做的就是写入磁盘。
这个对象也应该处理运行时权限吗? 对象是否一开始就不能写(通过标志),如果我们获得许可,标志将交换?
我很高兴知道你们中的一些人是如何做到这一点的。 谢谢!
权限是针对整个应用授予的,而不是针对单个对象。
如果您的应用获得一次权限,则无需再次请求。
在您的情况下,您可以在写入文件之前甚至在创建对象之前检查并请求必要的权限。
最佳做法是在使用需要权限的功能之前在上下文中请求权限。
检查我的图书馆以轻松处理权限。只需获取上下文参考,您就可以从任何地方请求权限。
您的问题没有一个明确的答案。您的问题通常与软件架构有关。所以可能会有很多不同的意见。我的给你。
通常,您希望 class 只负责一项工作。因此,记录器只记录消息,但不太关心权限。
所以我想说这通常是关于如何设计 API 并使其易于使用的问题。
例如,假设我们有一个 Logger 接口:
interface Logger {
void d(String tag, String message);
}
然后我们介绍一个具体的实现叫FileLogger
:
final class FileLogger implements Logger {
@Override
public void d(String tag, String message) {
// write a message to a file somehow
}
}
这里的问题是,如果尚未授予权限,是否应该 FileLogger#d
失败并返回 SecurityException
?或者它应该以某种方式警告开发人员?
就个人而言,在这种情况下,我会修改 FileLogger
以在尚未授予权限时不失败,但必须在应用程序的另一部分授予权限本身。
final class FileLogger implements Logger {
@Override
public void d(String tag, String messsage) {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
// write a log to a file
}
}
}
我们再来看一个例子。假设我们有一个名为 LocationApi
:
interface LocationApi {
@Nullable
Location getLastLocation();
}
用户必须向应用程序授予权限,这样它才能获得他最后的位置。如果应用程序没有权限,立即失败是否很关键?我会说是的!
这个接口的实现看起来像这样:
final class LocationApiImpl implements LocationApi {
@Nullable
public Location getLastLocation() {
if (ContextCompat.checkSelfPermission(..) != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException();
}
// obtain a location
}
}
P.S。有一个特殊的注释 RequiresPermission 可以帮助您指示某个方法需要权限,否则它可能会抛出 SecurityException
.
然后我们可以这样修改LocationApi
界面:
interface LocationApi {
@RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
@Nullable
Location getLastLocation();
}