我有一项服务,使用Firebase云消息传递使用带参数集的FCM数据消息与其Android客户端进行通信collapse_key
.从有关可折叠键的文档:
当有较新的消息呈现较旧的线程时,相关消息与客户端应用程序无关,FCM将替换旧消息.例如,发送到同步或过时的通知消息.
这就是我要找的东西.我不需要所有更新,只需要最后一个.但是,如果用户在线,我需要尽快.
但是,我得到一个奇怪的速率限制,不会导致任何HTTP错误代码.它很容易重现,只需要连续20条数据消息并监控android FirebaseMessagingService.onMessageReceived
:
for i in {1..20}; do
curl -v -X POST --header "Authorization: key=$SERVER_KEY" \
--Header "Content-Type: application/json" \
https://fcm.googleapis.com/fcm/send \
-d "{\"to\":\"$CLIENT_TOKEN\", \
\"data\":{\"counter\":\"$i\"}, \
\"priority\":\"high\", \
\"collapse_key\": \"test\" \
}"
done
Run Code Online (Sandbox Code Playgroud)
上面的bash脚本有点难以阅读,但我有一个counter
我感兴趣的变量.
收到一些消息后(counter=~10
)它会停止,您需要切换网络状态以获取最后一条消息counter=20
.最后一条消息也会在几分钟(通常约10分钟)后出现,此时请求进行火力登记(?).
collapse_key
从上面的curl命令中删除会导致收到所有20条消息(其中counter={1..20}
).
所以,问题是:这是一个错误吗?或者我关闭(/率限制),因为我"滥用"界面(因为所有请求都发回一个200
响应,我以为我没事).
如何使用正则表达式获取字符串中最后一个逗号后的内容?
例:
abcd,fg;ijkl, cas
Run Code Online (Sandbox Code Playgroud)
输出应该是 cas
注意:最后一个逗号和'c'
字符之间还有一个空格,也需要删除.此模式在最后一个逗号后只包含一个空格.
我找不到任何官方文档说Component.repaint
从除了事件调度线程(EDT)之外的另一个线程调用是安全的.
是这样吗?我在哪里可以找到一些文档/代码?
我有一个问题,我需要快速比较两个输入流.
今天我有这样的功能:
private boolean isEqual(InputStream i1, InputStream i2) throws IOException {
try {
// do the compare
while (true) {
int fr = i1.read();
int tr = i2.read();
if (fr != tr)
return false;
if (fr == -1)
return true;
}
} finally {
if (i1 != null)
i1.close();
if (i2 != null)
i2.close();
}
}
Run Code Online (Sandbox Code Playgroud)
但它真的很慢.我想使用缓冲读取,但还没有想出一个好方法.
一些额外的东西使它更难:
我需要一个实用的解决方案 - 代码!:)
像标题一样; 关闭FileChannel
基础文件流吗?
从AbstractInterruptibleChannel.close()
API文档中,您可以阅读:
关闭此频道.
如果通道已经关闭,则此方法立即返回.否则,它将通道标记为已关闭,然后调用该
implCloseChannel
方法以完成关闭操作.
哪个调用AbstractInterruptibleChannel.implCloseChannel
:
关闭此频道.
close方法调用此方法以执行关闭通道的实际工作.仅当通道尚未关闭时才会调用此方法,并且永远不会多次调用此方法.
此方法的实现必须安排在此通道上的I/O操作中阻塞的任何其他线程立即返回,方法是抛出异常或正常返回.
这并没有说明关于流的任何事情.事实上,当我这样做时:
public static void copyFile(File from, File to)
throws IOException, FileNotFoundException {
FileChannel sc = null;
FileChannel dc = null;
try {
to.createNewFile();
sc = new FileInputStream(from).getChannel();
dc = new FileOutputStream(to).getChannel();
long pos = 0;
long total = sc.size();
while (pos < total)
pos += dc.transferFrom(sc, pos, total - pos);
} finally {
if (sc != null)
sc.close();
if (dc != null)
dc.close(); …
Run Code Online (Sandbox Code Playgroud) 我想提取绝对路径的名称.如果我有一个值为/ mnt/sdcard/Videos/Videoname的字符串,我想保存一个值为Videoname的字符串.
字符串正在改变,我以前无法获得斜线数.我怎么能从最后一个斜线中分割一个子串?
/ mnt/sdcard/Videos/Videoname - > Videnoname
我想得到调用方法java.lang.reflect.Method
.不是方法的名称.
以下是如何获取调用者类的示例.
// find the callers class
Thread t = Thread.getCurrentThread();
Class<?> klass = Class.forName(t.getStackTrace()[2].getClassName());
// do something with the class (like processing its annotations)
...
Run Code Online (Sandbox Code Playgroud)
它仅用于测试目的!
我想知道数据使用历史,并注意到"新"android-6 NetworkStatsManager
似乎是积极的(我已经使用TrafficStats
了一段时间,但不会覆盖任何重启之前的任何东西).
从API文档:
注意:此API需要权限PACKAGE_USAGE_STATS,这是系统级权限,不会授予第三方应用程序.但是,声明权限意味着使用API的意图,并且设备的用户可以通过"设置"应用程序授予权限.配置文件所有者应用程序被自动授予查询其管理的配置文件上的数据的权限(即,除querySummaryForDevice(int,String,long,long)之外的任何查询).设备所有者应用程序同样可以访问主要用户的使用数据.
我想知道聚合级别的数据使用情况,而不是使用数据的应用程序,所以我试着像这样使用它:
NetworkStatsManager service = context.getSystemService(NetworkStatsManager.class);
NetworkStats.Bucket bucket =
service.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, null, from, to);
...
Run Code Online (Sandbox Code Playgroud)
不幸的是,抛出一个SecurityException
:
java.lang.SecurityException: NetworkStats: Neither user 10174 nor current process has android.permission.READ_NETWORK_USAGE_HISTORY.
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.net.INetworkStatsSession$Stub$Proxy.getDeviceSummaryForNetwork(INetworkStatsSession.java:259)
at android.app.usage.NetworkStats.getDeviceSummaryForNetwork(NetworkStats.java:316)
at android.app.usage.NetworkStatsManager.querySummaryForDevice(NetworkStatsManager.java:100)
...
Run Code Online (Sandbox Code Playgroud)
android.permission.READ_NETWORK_USAGE_HISTORY
第三方应用不允许该权限.所以这似乎是一个死胡同.
但是,我深入研究了内部结构,发现您可以使用内部/隐藏API执行相同的操作而无需请求任何权限:
INetworkStatsService service =
INetworkStatsService.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
INetworkStatsSession session = service.openSession();
NetworkTemplate mobileTemplate = NetworkTemplate.buildTemplateMobileWildcard();
int fields = NetworkStatsHistory.FIELD_RX_BYTES | NetworkStatsHistory.FIELD_TX_BYTES;
NetworkStatsHistory mobileHistory = session.getHistoryForNetwork(mobileTemplate, fields);
for (int i = 0; i < …
Run Code Online (Sandbox Code Playgroud) permissions android android-6.0-marshmallow networkstatsmanager
有没有办法确定给定对象是枚举值?
x.isInstanceOf[Enumeration.$Value]
似乎不起作用,从我对路径依赖类型的理解,不应该.
我想写一个给出任何Enumeration值的函数,返回它的id.或者,将Enumeration转换为Int的隐式也很棒.
Google使用varargs
参数的原因是什么AsyncTask
?例如,方法execute()
,doInBackground()
以及publishProgress()
所有使用[Type]...
的符号.
我认为这使得"更难"使用,所以他们必须有一些我忽略的好理由?
所以,要么我们没有参数,要么有一个或多个参数.让我们分解一下:
没有参数(简单):Params
参数是Void
,就是这样.(这些方法不能使用它......所以非常安全.)
一个参数:至少在这里,我觉得有必要在doInBackground()
方法的开头进行检查.例如,这是一个接收Integer
和生成类型结果的任务Double
:
public Double doInBackground(Integer... myParameters) {
// we are only expecting one parameter
if (myParameters.length != 1)
throw new IllegalArgumentException("!= 1");
return 100d * myParameters[0];
}
Run Code Online (Sandbox Code Playgroud)多个参数.现在这里必须是Google做出正确选择的地方吗?但正如我所看到的那样,您要么对相同类型的参数列表感兴趣,要么需要不同类型的参数.谷歌只解决了其中一种情况(不同类型你需要某种通用界面.在很多情况下,我最终Object...
得到的并不是真正的类型安全......)
那么,如果我们完全删除它会有什么问题varargs
呢?这是方法的一个子集:
class AsyncTask<Param, Progress, Result> {
abstract Result doInBackground(Param param);
void publishProgress(Progress progress) { ... } …
Run Code Online (Sandbox Code Playgroud) java ×7
android ×4
awt ×1
compare ×1
file ×1
firebase ×1
inputstream ×1
nio ×1
permissions ×1
reflection ×1
regex ×1
scala ×1
swing ×1