如果您想了解即使在另一个线程上调用subscribeOn和,也可以在主线程上运行的知识,那么本篇文章将是您的不二之选。我们将深入剖析即使在另一个线程上调用subscribeOn的各个方面,并为您解答,
如果您想了解即使在另一个线程上调用subscribeOn和,也可以在主线程上运行的知识,那么本篇文章将是您的不二之选。我们将深入剖析即使在另一个线程上调用subscribeOn的各个方面,并为您解答,也可以在主线程上运行的疑在这篇文章中,我们将为您介绍即使在另一个线程上调用subscribeOn的相关知识,同时也会详细的解释,也可以在主线程上运行的运用方法,并给出实际的案例分析,希望能帮助到您!
本文目录一览:- 即使在另一个线程上调用subscribeOn(),也可以在主线程上运行
- Android JNI功能在主线程上运行?
- android – AsyncTask onPostExecute没有在主线程上运行?
- android – 如何在主线程上运行服务?
- android – 广播接收器在主线程上运行?
即使在另一个线程上调用subscribeOn(),也可以在主线程上运行
我的一项活动遇到了一个奇怪的问题。从拍照/录像回来时,onActivityResult
我正在显示一个对话框,允许用户命名相机。用户按下“确定”后,我将onNext()
使用所请求的文件名发送给主题,该主题将复制文件(并显示进度对话框)。
由于某种原因map()
,即使我调用,总是在主线程上调用执行复制的函数subscribeOn(Schedulers.io())
。
@Overrideprotected void onActivityResult(final int requestCode, int resultCode, Intent intent) { ... final PublishSubject<String> subject = PublishSubject.create();` mSubscription = subject .subscribeOn(Schedulers.io()) .map(new Func1<String, String>() { @Override public String call(String fileName) { Log.I.d(TAG,"map"); return doSomeIOHeavyFuncition(); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(final String fullPath) { Log.d(TAG,"onNext"); doSomethingOnUI(fullPath); subject.onCompleted(); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { ... } }, new Action0() { @Override public void call() { ... } }); final AlertDialog dialog = new AlertDialog.Builder .... .create() .show(); dialog.getButton(DialogInterface.BUTTON_POSITIVE) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String someString = getStringFromDialog(dialog); dialog.dismiss(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(input.getWindowToken(), 0); showProgressDialog(); subject.onNext(someString); } });}
更改subscribeOn(Schedulers.io())
呼叫以observeOn(Schedulers.io())
解决问题。我还是想知道为什么它不起作用…
答案1
小编典典subscribeOn
并且observeOn
是那里最混乱的运营商。前者确保订阅副作用在指定的调度程序(线程)上发生,但这并不意味着值也将在该线程上弹出。
例如,如果您的观察者在订阅时打开了一个网络连接,则您不希望该链接在主线程上运行,因此,您需要subscriptionOn来指定该订阅的位置,从而创建网络连接。
当数据最终到达时,发出线程可以是任何东西,调度程序之一或后台普通旧线程。由于我们不知道或不喜欢该线程,因此我们希望将对数据的观察移到另一个线程。这是observeOn的作用:确保操作符之后的操作符将在指定的调度程序上执行其onNext逻辑。Android开发人员已经使用它来将对值的观察移回主线程。
但是很少解释的是,当您希望在最终结果再次落入主线程之前又需要在主线程上进行一些额外的计算时会发生什么:使用多个observeOn
运算符:
source.observeOn(Schedulers.computation()).map(v -> heavyCalculation(v)).observeOn(Schedulers.io()).doOnNext(v -> { saveToDB(v); }).observeOn(AndroidSchedulers.mainThread())...
Android JNI功能在主线程上运行?
解决方法
android – AsyncTask onPostExecute没有在主线程上运行?
这应该可以防止用户在没有实际阻塞主线程的情况下操作Activity.
但是,我注意到有几次ProgressDialog从未被解雇,用户卡住了. AsyncTask已完成,onPostExcute已执行,但仍显示ProgressDialog. ProgressDialog没有机会被解雇,用户被卡在屏幕上.他们唯一的选择是访问Android设置应用并强制停止我的应用程序.
有谁知道为什么会这样?我该怎么办才能修复它?
相关代码:
这是我展示ProgressDialog并启动任务的方式:
mProgress = ProgressDialog.show(this,"","Syncing...",true); (new MyAsyncTask()).execute(intUserId);
这是该任务的onPostExcute.没有“@Override”
protected void onPostExecute(Boolean result) { if (mProgress != null) { mProgress.dismiss(); mProgress = null; } }
解决方法
>确保在UI线程上调用了asynctack.execute().>在onPostExcute()上使用@Override以确保它已正确定义.
android – 如何在主线程上运行服务?
在按钮上单击我创建新线程然后启动服务.
Thread t = new Thread(){ public void run(){ mIntent= new Intent(MainActivity.this,ConnectonService.class); mIntent.putExtra("KEY1","Value used by the service"); context.startService(mIntent); } }; t.start();
然后在服务上,我尝试打开套接字并与服务器连接
@Override public int onStartCommand(Intent intent,int flags,int startId) { //Todo do something useful try { InetAddress serverAddr = InetAddress.getByName(SERVER_IP); socket = new Socket(serverAddr,SERVERPORT); Scanner scanner = new Scanner(socket.getInputStream()); message = scanner.nextLine(); } catch (IOException e) { e.printstacktrace(); } return Service.START_NOT_STICKY; }
但是当我打电话给我时,我有错误
08-30 08:56:49.268: E/AndroidRuntime(3751): java.lang.RuntimeException: Unable to start service com.example.testofconnection.ConnectonService@40ef02a8 with Intent { cmp=com.example.testofconnection/.ConnectonService (has extras) }: android.os.networkonmainthreadException*
我认为问题是服务在主线程上,但是我找不到如何在新的(独立)线程上启动服务以保持连接活动?
解决方法
public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { // this method is called in background thread } @Override public IBinder onBind(Intent intent) { return null; } }
在您的活动中,您将按以下方式启动服务.
startService(new Intent(this,MyIntentService.class));
如果您需要持久的服务,您可以创建一个正常的服务并在那里启动一个线程.这是一个例子.确保将其作为“前台”服务启动.这将使服务运行更长时间而不会被Android杀死.
public class MyAsyncService extends Service { private Runnable runnable = new Runnable() { @Override public void run() { while(true) { // put your socket-code here ... } } } @Override public void onCreate() { // start new thread and you your work there new Thread(runnable).start(); // prepare a notification for user and start service foreground Notification notification = ... // this will ensure your service won't be killed by Android startForeground(R.id.notification,notification); } }
android – 广播接收器在主线程上运行?
这是我注册我的接收器的方式:
mMessageReceiver = new MQTTMessageReceiver(); IntentFilter intentFilter = new IntentFilter(MQTTService.MQTT_MSG_RECEIVED_INTENT); registerReceiver(mMessageReceiver,intentFilter);
解决方法
>不要在BoradcastReceiver中进行繁重的处理(但似乎
它不是一个选项)
>开始新的Thread或
AsyncTask或装载机,或任何线程机制
喜欢用.所以这将把计算密集的部分转移到
单独的线程,不阻止UI.
>正如axierjhtjz建议你的那样
可以运行IntentService(因为它创建了一个单独的工作
线程)与MQTTMessageReceiver(我假设这是你的
broadcastReceiver的子类,它将处理数据并通知UI
穿过另一个broadcastReceiver.
我个人建议使用第三种方式,因为它使您的应用程序更加模块化,这意味着更容易支持和扩展程序
编辑:我也考虑过第四种方式:
>您可以使用this method注册Receiver,提供一个Handler对象,用于标识将进行数据处理的Thread.
关于即使在另一个线程上调用subscribeOn和,也可以在主线程上运行的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android JNI功能在主线程上运行?、android – AsyncTask onPostExecute没有在主线程上运行?、android – 如何在主线程上运行服务?、android – 广播接收器在主线程上运行?等相关知识的信息别忘了在本站进行查找喔。
本文标签: