如果Service和IntentService主要差异是Service在主线程上运行而IntentService不是,并且后者在工作完成时完成,而我们必须调用stopService()或stopSelf()停止a Service.
这两个都可以简单地传递给startService().
怎么样JobService和JobIntentService?
我们来看下面的代码片段:
JobInfo job = new JobInfo.Builder(id, new ComponentName(context, ExampleJobService.class))
.build();
JobScheduler scheduler = (JobScheduler) context
.getSystemService(Context.JOB_SCHEDULER_SERVICE);
scheduler.schedule(job);
Run Code Online (Sandbox Code Playgroud)
可以ExampleJobService.class参考a JobService和a JobIntentService?
将行为相同,与Service和IntentService(除了JobScheduler可能不会立即开始工作)?
我的应用程序使用此经典模式来安排定期任务:
AlarmManager(通过setExactAndAllowWhileIdle(),因为即使在Doze中也必须关闭)设置确切的警报IntentService从onReceive()通过WakefulBroadcastReceiver.startWakefulService()onHandleIntent()并WakefulBroadcastReceiver.completeWakefulIntent()在完成后打电话.今天我将targetSdkVersion更新为26,并面临着WakefulBroadcastReceiver被弃用的可怕事实.
我立即去阅读API文档,发现以下内容:
从Android O开始,后台检查限制使这个类不再普遍有用.(从接收广播开始提供服务通常是不安全的,因为您无法保证您的应用程序此时处于前台,因此可以这样做.)相反,开发人员应该使用
android.app.job.JobScheduler安排一项工作,这并不要求应用程序在执行此操作时保持唤醒锁定(系统将负责为该作业保持唤醒锁定).
这对我来说有点令人困惑,我真的不明白为什么AlarmManager.setExactAndAllowWhileIdle()不能让设备保持清醒状态的目的是什么.
因为我看到我无法设置运行作业的确切时间JobScheduler,只有条件(例如网络类型或充电状态)所以我不知道该怎么做.
我想到了
使用AlarmManager和JobScheduler在一起
设置闹钟(带setExactAndAllowWhileIdle())并JobScheduler立即开始作业(通过)onReceive().既然JobScheduler提供了WakeLock,WakefulBroadcastReceiver就不需要了.
(这有意义吗?)
要么
WakefulBroadcastReceiver,尽管被弃用.我非常感谢你对此事的任何建议.
我正在使用以下代码发送DatagramPacket到给定地址:
InetAddress address = InetAddress.getByName(anIPAddress);
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(packetBytes, packetBytes.length,
address, port);
socket.send(packet);
socket.close();
Run Code Online (Sandbox Code Playgroud)
它工作正常,但是Exception当没有可用的互联网连接时,为什么这个代码不会抛出任何东西?
我关闭了Wi-Fi和移动数据,这些代码仍然可以执行而没有任何错误.
有没有办法确保实际发送数据包?
(我不在乎它是否到达目的地,我只想确保它被发送)
在我的Angular服务中,我有以下方法:
// creates an Item and returns the ID of the created Item
createItem(item: Item): Observable<ItemId> {
return this.http.post<ItemId>('some_api_url', item);
}
// returns all Items
getAllItems(): Observable<Item[]> {
return this.http.get<Item[]>('some_api_url');
}
Run Code Online (Sandbox Code Playgroud)
在我的模板中,我显示列表中的项目.
我希望能够创建一个新项目,然后重新加载列表(包括新创建的项目),所以我实现了以下内容:
this.itemService.createItem(item)
.pipe(
switchMap(createdId => this.itemService.getAllItems())
).subscribe(result => {
this.items = result;
});
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,但最后我还想做一些处理createdId:
this.itemService.createItem(item)
.pipe(
switchMap(createdId => this.itemService.getAllItems())
).subscribe(result => {
this.items = result;
// i would like to use createdId here as well
});
Run Code Online (Sandbox Code Playgroud)
所以我想出了以下内容:
this.itemService.createItem(item)
.pipe(
switchMap(createdId =>
combineLatest(this.itemService.getAllItems(), of(createdId)))
).subscribe(result => { …Run Code Online (Sandbox Code Playgroud) 我有一个在端口 8888 上运行的 Spring Boot 后端应用程序和一个在 4200 上运行的 Angular 前端应用程序。
在我的 Spring Boot 应用程序中,我定义了以下 bean 来处理 CORS:
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
};
}
Run Code Online (Sandbox Code Playgroud)
我的HttpSecurity配置如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
// ... the rest of the config
}
Run Code Online (Sandbox Code Playgroud)
使用此配置一切正常,我可以从 Angular 应用程序成功调用我的 API。
但我想启用 CSRF,所以我将安全配置更改为以下内容:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
// ... the …Run Code Online (Sandbox Code Playgroud) 这是原子操作吗?
我的意思是,在方向更改期间,主线程上是否有可能执行其他任何操作?
例如,假设主线程上的流程是这样的:
someOperation - > orientationChangeStart - > someOtherOperation - > orientationChangeEnd
这可能吗?
someOtherOperation在方向更改正在进行时,是否可以在UI线程上执行?
提前致谢.
在我的 Android 应用程序中,我在RecyclerView使用 Room 和 Paging 库中显示数据。
我的实现与AsyncPagedListDiffer 文档中的示例非常相似。
流程如下:
相应的Observer将更改传递给Adapter:
myLiveData.observe(viewLifecycleOwner, Observer {
myAdapter.submitList(it)
})
Run Code Online (Sandbox Code Playgroud)该AsyncPagedListDiffer计算差异并相应地更新列表
我的问题是第 3 步的性能下降。
即使我只在列表顶部插入一个项目,不同的项目也必须检查所有项目(这非常低效,尤其是对于较大的数据集),而简单的notifyItemInserted(0)调用就足够了。
有没有办法解决这种行为?
例如,我可以告诉它不必检查所有项目吗?或者任何其他解决方案?
我真的很感激任何建议。
在我的 Web 应用程序中,我FormData从 Angular 前端发送到 Spring Boot 服务器。
我有以下Attachment模型:
export interface Attachment {
file: File;
comment: string;
}
Run Code Online (Sandbox Code Playgroud)
我想通过一个 发送多个附件FormData。
目前我可以使用以下代码成功发送文件:
attachments: Attachment[] = [];
// pushing some data to the array
const data = new FormData();
for (const attachment of this.attachments) {
data.append('attachments', attachment.file);
}
// POSTing data to the server
Run Code Online (Sandbox Code Playgroud)
但这不包括与文件一起的注释。
我还想以服务器可以准确识别哪个注释属于哪个文件的方式包含注释。
我不能简单地做类似的事情data.append('attachments', attachment),因为FormData只能有字符串和Blob值。
我能想到的最好的想法是将注释添加到FormData文件名作为键:
for (const attachment of this.attachments) {
data.append('attachments', attachment.file);
// …Run Code Online (Sandbox Code Playgroud) 我正在使用AlarmManager多个活动在我的应用中设置闹钟.
为了避免冗余代码,我创建了以下类:
public class CustomAlarmManager {
private static final String SHARED_PREF_REQUEST_CODE = "requestCode";
private static final String KEY_REQUEST_CODE = "kRequestCode";
private CustomAlarmManager() {
}
public static void setNewAlarm(Context context, long timeInMillis) {
Intent intent = new Intent(SomeOtherClass.ALARM_ACTION);
intent.putExtra(SomeOtherClass.KEY_ALARM_TIME, timeInMillis);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context.getApplicationContext(),
getNewCode(context),
intent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= 23) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
timeInMillis, pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
am.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
} else {
am.set(AlarmManager.RTC_WAKEUP, timeInMillis, pendingIntent);
}
} …Run Code Online (Sandbox Code Playgroud) 我正在使用Spring Boot和Thymeleaf开发应用程序.
我的自定义登录页面中有以下代码段:
<p th:if="${param.logout}">Logged out successfully</p>
Run Code Online (Sandbox Code Playgroud)
此段落与以下安全配置相关联:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "*.css").permitAll()
.antMatchers("/myendpoint").authenticated()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.permitAll();
}
Run Code Online (Sandbox Code Playgroud)
因此,在注销后,用户被重定向到/login?logout并显示注销消息.
我的问题是当用户/login?logout通过简单地写入http://myserver:8080/login?logout浏览器明确导航到时,也会显示此消息.
是否可以阻止用户直接访问/login?logout(因此仅在实际注销时显示消息)?
在我的Android应用程序中,我定义了一个非常基本的PreferenceScreen:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:entries="@array/test_entries"
android:entryValues="@array/test_values"
android:key="key_test1"
android:title="Test title 1" />
<CheckBoxPreference
android:key="key_test2"
android:summary="Test description 1"
android:title="Test title 2" />
</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)
并实现了相应的PreferenceFragmentCompat类:
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings, rootKey)
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用的依赖:
implementation "com.android.support:preference-v7:28.0.0"
Run Code Online (Sandbox Code Playgroud)
以及承载以下内容的布局代码Fragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.activity.MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/mainToolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize" />
<fragment
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
一切都很好,除了每个偏好左侧有一个巨大的空白区域:
这个问题的原因是什么,我该如何预防呢?
编辑:
似乎问题是图标的空间被保留,即使我们没有使用偏好条目的图标. …
为了避免我的Angular应用程序出现内存泄漏,我使用以下众所周知的模式从Observables退订:
unsubscribe = new Subject();
ngOnInit() {
this.myService.getStuff()
.pipe(takeUntil(this.unsubscribe))
.subscribe(result => {
// processing the result
});
}
ngOnDestroy() {
this.unsubscribe.next();
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,但是在某些示例中,我注意到除了之外,complete()还调用了:Subjectnext()
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete(); // like this
}
Run Code Online (Sandbox Code Playgroud)
complete()这里打电话是必要的吗?如果是这样,为什么?complete()在这种情况下不打电话会有什么后果?
作为一种替代方案Intent,我Fragment在Activity重新创建期间将数据保存在保留的无头中(我保存的对象可能非常大,并且它不符合a的大小限制Intent,我认为这是比序列化更快的方法 -例如,反序列化为JSON).
虽然我的实现有点不同,但我从这篇Google文档中得到了这个想法.
的Fragment:
public class DataFragment extends Fragment {
private Data data;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public void setData(Data data) {
this.data = data;
}
public Data getData() {
return data;
}
}
Run Code Online (Sandbox Code Playgroud)
我Fragment在onSaveInstanceState()我的方法中将数据保存到此Activity:
@Override
protected void onSaveInstanceState(Bundle outState) {
FragmentManager fm = getSupportFragmentManager();
dataFragment = (DataFragment) fm.findFragmentByTag(TAG_DATA);
if (dataFragment == null) {
dataFragment = …Run Code Online (Sandbox Code Playgroud) android ×8
angular ×4
javascript ×4
java ×3
rxjs ×2
spring ×2
kotlin ×1
spring-boot ×1
thymeleaf ×1
typescript ×1
udp ×1