Tag: 多线程

例外:尽管我在另一个线程上进行了subsribed,但不能在UI线程上调用blockingConnect

我有这样的调用: val connectionResult = googleApiClient.blockingConnect() 这是这个例外的原因: java.lang.IllegalStateException:不能在UI线程上调用blockingConnect at com.google.android.gms.common.internal.zzbp.zza(Unknown Source) at com.google.android.gms.common.api.internal.zzbd.blockingConnect(Unknown Source) at com.elstatgroup.elstat.NexoLocationManager.startLocationUpdatesGmsApi(NexoLocationManager.kt:510) at com.elstatgroup.elstat.NexoLocationManager.startLocationUpdates(NexoLocationManager.kt:498) at com.elstatgroup.elstat.NexoLocationManager.appendRSSIEvent(NexoLocationManager.kt:283) at com.elstatgroup.elstat.NexoLocationManager.appendRSSIEvent(NexoLocationManager.kt:273) at com.elstatgroup.elstat.NexoLocationTest.testAppendLocationEvents(NexoLocationTest.kt:111) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:497) at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:228) at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:110) at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:37) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at […]

RxJava2 PublishSubject订阅服务器在使用SingleScheduler从多个线程调用时无法接收项目

我有以下的单元测试,我试图从不同的线程发送10个String ,并测试我从一个线程接收这些String 。 我的问题是,这个测试襟翼。 有时会成功,但有时我只会收到8或9项目,之后测试会挂起,直到闩锁超时。 我SingleScheduler以错误的方式使用SingleScheduler ? 我错过了别的吗? val consumerCallerThreadNames = mutableSetOf<String>() val messageCount = AtomicInteger(0) val latch = CountDownLatch(MESSAGE_COUNT) @Test fun someTest() { val msg = "foo" val subject = PublishSubject.create<String>() subject .observeOn(SingleScheduler()) .subscribe({ message -> consumerCallerThreadNames.add(Thread.currentThread().name) messageCount.incrementAndGet() latch.countDown() }, Throwable::printStackTrace) 1.rangeTo(MESSAGE_COUNT).forEach { Thread({ try { subject.onNext(msg) } catch (t: Throwable) { t.printStackTrace() } […]

发布到UI线程

我想在onCreate创建一个新线程,并使用View上的post与UI线程进行通信。 但是,编辑报表似乎并没有运行。 这是一个小例子: import android.app.Activity import android.os.Bundle import android.widget.TextView import kotlin.concurrent.* import org.jetbrains.anko.* class MainActivity: Activity(), AnkoLogger { protected override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val view = TextView(this) setContentView(view) thread() { info("before post") view.post({ info("inside post") }) info("after post") } } } 看日志,我只能看到before post和after post ,但从来没有inside post 。 我究竟做错了什么?

协程怎么比线程快?

我试图找到一种情况,将多线程更改为协程将加快处理受影响的代码部分。 据我发现,与线程相比,协程使用更少的CPU和堆空间,但我仍然无法找到协程比线程更快的情况。 虽然我知道,协程创建和上下文切换比使用线程的相应操作便宜得多,但是我在速度差异上没有察觉到结果(没有测量线程创建,两种情况都是完全相同的)。 那么,甚至有可能找到一个协程比线程更快执行的情况呢?

将通道桥接到一个序列

该代码基于Coroutines指南示例:扇出 val inputProducer = produce<String>(CommonPool) { (0..inputArray.size).forEach { send(inputArray[it]) } } val resultChannel = Channel<Result>(10) repeat(threadCount) { launch(CommonPool) { inputProducer.consumeEach { resultChannel.send(getResultFromData(it)) } } } 创建一个Sequence<Result>的正确方法是什么?

Android:为什么没有一个静态方法来获得主线程的处理程序?

我是Android开发的新手。 在处理Android中的线程时似乎有两个重要的类: Looper和Handler 。 有静态Looper.myLooper()和Looper.getMainLooper()方法分别获取当前线程的活套和UI线程的活套。 但是, Handler没有这样的静态方法。 例如,如果你想发布到UI线程,代码示例建议这样做: new Handler(Looper.getMainLooper()).post(new Runnable() { … 为什么Handler不公开一个看起来像这样的缓存的静态getMainHandler()方法? 这不会避免造成不必要的垃圾? private static final Handler mainHandler = new Handler(Looper.getMainLooper()); public static Handler getMainHandler() { return mainHandler; }

创建一个SingleBlockingQueue同步器

我试图创建一个SingleBlockingQueue<T>同步器,允许一个线程offer()一个元素给它,另一个线程将take()它。 在SingleBlockingQueue<T>中一次只保留一个T元素,如果前一个元素正在等待take线程take() ,则推送线程在offer()上被阻塞。 推送线程将继续推送项目,直到它调用setComplete() ,并且当isComplete()为false时,take线程将继续调用take() 。 如果正在等待某个元素,则线程将被阻塞。 这是我迄今为止的同步器。 import java.util.concurrent.atomic.AtomicBoolean; public final class SingleBlockingQueue<T> { private volatile T value; private final AtomicBoolean isComplete = new AtomicBoolean(false); private final AtomicBoolean isPresent = new AtomicBoolean(false); public void offer(T value) throws InterruptedException { while (isPresent.get()) { this.wait(); } this.value = value; synchronized(this) { this.notifyAll(); } } public boolean […]

为什么我的Android应用程序中的第一个计算速度很慢,而所有后续的计算都很快

我正在使用symja android库来为我正在构建的测验应用程序执行数学计算。 我所有的计算都是通过将一个字符串(如“1 + 3 +(4/2)”)传递给名为ExprEvaluator()的库中的一个类来执行的。 一个示例的用法是 ExprEvaluator().evaluate("1+3 + (4/2)") //Kotlin 当我运行我的测验应用程序并首次回答问题时,主UI线程将冻结,因为它执行计算,但所有后续计算将非常快。 下面,我列出了一系列我为了解决问题而尝试的策略。 注:我已经注入ExprEvaluator类与匕首,它作为一个单身存在 class ChallengeUtils { @Inject lateinit var exprEvaluator: ExprEvaluator … fun evaluate(expression: String?): IExpr? { try { return exprEvaluator.evaluate(expression) } catch (e: Exception) { throw (e) } } 策略1:将计算卸载到一个单独的线程结果:在初始计算时间没有什么差别,实际上导致更多的问题,因为我需要在主UI线程上的结果。 所有后续的计算都像往常一样快。 策略2:在我的SplashScreen活动上运行一个简单的初始计算。 结果:这是我找到的最好的解决方案,但唯一的缺点是我的启动画面太长。 一旦进入主应用程序,测验表现非常好。 策略3:在启动画面中运行一个新的线程活动结果:这解决了启动画面加载太长的问题,但如果我在主线程上回答一个问题,并在其他线程的初始计算完成之前检查它的正确性,UI线程冻结。 我注意到第一个评估调用总是很慢,不管我传入的字符串是什么,我可以通过“1”,评估大约需要4秒,而所有后续更复杂的评估最多需要几毫秒。 即使我使用ExprEvaluator类的新实例来进行每一个sincle计算,如下所示: fun evaluate(expression: String?): IExpr? { try […]

如何在android的后台运行一段代码?

我试图做一个应用程序,从手机加载联系人列表,但这需要大量的时间根据联系人的数量。 我想在后台运行加载联系人列表,以便它不会减慢应用程序。 我正在使用下面的函数来加载联系人信息。 void loadContacts() { ContentResolver contentResolver=getContentResolver(); Cursor cursor=contentResolver.query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null); if(cursor.getCount() > 0) { while (cursor.moveToNext()) { String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); Bitmap photo = retrieveContactPhoto(id); int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))); String phoneNumber = null; if (hasPhoneNumber > 0) { Cursor cursor2 = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); […]

Android:运行4个异步任务(与Rest API一起工作),完成所有任务后等待并启动另一个任务

我有一些异步任务的问题。 我试图运行从last.fm休息API获取数据的4个异步任务。 我的任务是: 运行4个任务(计数无关紧要,但必须大于1)异步或并行 从last.fm rest api获取数据(用于从last.fm api获取数据,我使用了de.umass.lastfm java库) 等待完成所有任务 用获取的数据开始另一个活动 调用异步任务的函数: <pre>override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_animation) initViewElements(); mArtistName = intent.getStringExtra("ARTIST_NAME"); Log.i(TAG, mArtistName); setAnimationData(); getArtistData(mArtistName); startActivity(Intent(this, DetailsActivity::class.java)) }</pre> 功能介绍了我的任务 <pre> private fun getArtistData(name: String) { val getArtistDataAsync = object : AsyncTask<String, Void, Artist>() { override fun doInBackground(vararg args: String?): Artist? { return Artist.getInfo(args[0], […]