From 3996f1824dd92e01195815d6781ac3d602c48087 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Tue, 8 Jan 2019 00:47:25 +0000 Subject: [PATCH] Migrate from AsyncTask to anko's doAsync. --- app/build.gradle | 2 + .../ui/CollectionMembersListFragment.kt | 62 ++-- .../syncadapter/ui/JournalItemActivity.kt | 298 +++++++++--------- .../ui/journalviewer/ListEntriesFragment.kt | 41 +-- 4 files changed, 204 insertions(+), 199 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c88fd41e..e54fd989 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -127,6 +127,8 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation "org.jetbrains.anko:anko-commons:0.10.4" + def acraVersion = '5.2.1' implementation "ch.acra:acra-mail:$acraVersion" diff --git a/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt index a208b020..b520c0d9 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/CollectionMembersListFragment.kt @@ -2,7 +2,6 @@ package com.etesync.syncadapter.ui import android.accounts.Account import android.content.Context -import android.os.AsyncTask import android.os.Bundle import android.support.v4.app.ListFragment import android.support.v7.app.AlertDialog @@ -20,13 +19,16 @@ import com.etesync.syncadapter.model.JournalModel import io.requery.Persistable import io.requery.sql.EntityDataStore import okhttp3.HttpUrl +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.uiThread +import java.util.concurrent.Future class CollectionMembersListFragment : ListFragment(), AdapterView.OnItemClickListener, Refreshable { private lateinit var data: EntityDataStore private lateinit var account: Account private lateinit var info: CollectionInfo private lateinit var journalEntity: JournalEntity - private var asyncTask: AsyncTask<*, *, *>? = null + private var asyncTask: Future? = null private var emptyTextView: TextView? = null @@ -48,7 +50,30 @@ class CollectionMembersListFragment : ListFragment(), AdapterView.OnItemClickLis } override fun refresh() { - asyncTask = JournalMembersFetch().execute() + asyncTask = doAsync { + var members: List? = null; + try { + val settings = AccountSettings(context!!, account!!) + val httpClient = HttpClient.create(context!!, settings) + val journalsManager = JournalManager(httpClient, HttpUrl.get(settings.uri!!)!!) + + val journal = JournalManager.Journal.fakeWithUid(journalEntity!!.uid) + members = journalsManager.listMembers(journal) + } catch (e: Exception) { + uiThread { + emptyTextView!!.text = e.localizedMessage + } + } + + uiThread { + val listAdapter = MembersListAdapter(context!!) + setListAdapter(listAdapter) + + listAdapter.addAll(members) + + emptyTextView!!.setText(R.string.collection_members_list_empty) + } + } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -94,37 +119,6 @@ class CollectionMembersListFragment : ListFragment(), AdapterView.OnItemClickLis } } - private inner class JournalMembersFetch : AsyncTask() { - override fun doInBackground(vararg voids: Void): MembersResult { - try { - val settings = AccountSettings(context!!, account!!) - val httpClient = HttpClient.create(context!!, settings) - val journalsManager = JournalManager(httpClient, HttpUrl.get(settings.uri!!)!!) - - val journal = JournalManager.Journal.fakeWithUid(journalEntity!!.uid) - return MembersResult(journalsManager.listMembers(journal), null) - } catch (e: Exception) { - return MembersResult(null, e) - } - - } - - override fun onPostExecute(result: MembersResult) { - if (result.throwable == null) { - val listAdapter = MembersListAdapter(context!!) - setListAdapter(listAdapter) - - listAdapter.addAll(result.members) - - emptyTextView!!.setText(R.string.collection_members_list_empty) - } else { - emptyTextView!!.text = result.throwable.localizedMessage - } - } - - internal inner class MembersResult(val members: List?, val throwable: Throwable?) - } - companion object { fun newInstance(account: Account, info: CollectionInfo): CollectionMembersListFragment { diff --git a/app/src/main/java/com/etesync/syncadapter/ui/JournalItemActivity.kt b/app/src/main/java/com/etesync/syncadapter/ui/JournalItemActivity.kt index 70eebf04..289a883e 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/JournalItemActivity.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/JournalItemActivity.kt @@ -27,10 +27,13 @@ import com.etesync.syncadapter.model.JournalEntity import com.etesync.syncadapter.model.SyncEntry import com.etesync.syncadapter.ui.journalviewer.ListEntriesFragment.Companion.setJournalEntryView import ezvcard.util.PartialDate +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.uiThread import java.io.IOException import java.io.StringReader import java.text.SimpleDateFormat import java.util.* +import java.util.concurrent.Future class JournalItemActivity : BaseActivity(), Refreshable { private var journalEntity: JournalEntity? = null @@ -123,7 +126,7 @@ class JournalItemActivity : BaseActivity(), Refreshable { class PrettyFragment : Fragment() { internal lateinit var info: CollectionInfo internal lateinit var syncEntry: SyncEntry - private var asyncTask: AsyncTask<*, *, *>? = null + private var asyncTask: Future? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { var v: View? = null @@ -134,11 +137,11 @@ class JournalItemActivity : BaseActivity(), Refreshable { when (info.type) { CollectionInfo.Type.ADDRESS_BOOK -> { v = inflater.inflate(R.layout.contact_info, container, false) - asyncTask = LoadContactTask(v).execute() + asyncTask = loadContactTask(v) } CollectionInfo.Type.CALENDAR -> { v = inflater.inflate(R.layout.event_info, container, false) - asyncTask = LoadEventTask(v).execute() + asyncTask = loadEventTask(v) } } @@ -151,186 +154,191 @@ class JournalItemActivity : BaseActivity(), Refreshable { asyncTask!!.cancel(true) } - private inner class LoadEventTask internal constructor(internal var view: View) : AsyncTask() { - override fun doInBackground(vararg aVoids: Void): Event? { + private fun loadEventTask(view: View): Future { + return doAsync { + var event: Event? = null val inputReader = StringReader(syncEntry.content) try { - return Event.fromReader(inputReader, null)[0] + event = Event.fromReader(inputReader, null)[0] } catch (e: InvalidCalendarException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } - return null - } + if (event != null) { + uiThread { + val loader = view.findViewById(R.id.event_info_loading_msg) + loader.visibility = View.GONE + val contentContainer = view.findViewById(R.id.event_info_scroll_view) + contentContainer.visibility = View.VISIBLE - override fun onPostExecute(event: Event) { - val loader = view.findViewById(R.id.event_info_loading_msg) - loader.visibility = View.GONE - val contentContainer = view.findViewById(R.id.event_info_scroll_view) - contentContainer.visibility = View.VISIBLE + setTextViewText(view, R.id.title, event.summary) - setTextViewText(view, R.id.title, event.summary) + setTextViewText(view, R.id.when_datetime, getDisplayedDatetime(event.dtStart?.date?.time!!, event.dtEnd?.date!!.time, event.isAllDay(), context)) - setTextViewText(view, R.id.when_datetime, getDisplayedDatetime(event.dtStart?.date?.time!!, event.dtEnd?.date!!.time, event.isAllDay(), context)) + setTextViewText(view, R.id.where, event.location) - setTextViewText(view, R.id.where, event.location) + val organizer = event.organizer + if (organizer != null) { + val tv = view.findViewById(R.id.organizer) as TextView + tv.text = organizer.calAddress.toString().replaceFirst("mailto:".toRegex(), "") + } else { + val organizerView = view.findViewById(R.id.organizer_container) + organizerView.visibility = View.GONE + } - val organizer = event.organizer - if (organizer != null) { - val tv = view.findViewById(R.id.organizer) as TextView - tv.text = organizer.calAddress.toString().replaceFirst("mailto:".toRegex(), "") - } else { - val organizerView = view.findViewById(R.id.organizer_container) - organizerView.visibility = View.GONE - } + setTextViewText(view, R.id.description, event.description) - setTextViewText(view, R.id.description, event.description) + var first = true + var sb = StringBuilder() + for (attendee in event.attendees) { + if (first) { + first = false + sb.append(getString(R.string.journal_item_attendees)).append(": ") + } else { + sb.append(", ") + } + sb.append(attendee.calAddress.toString().replaceFirst("mailto:".toRegex(), "")) + } + setTextViewText(view, R.id.attendees, sb.toString()) - var first = true - var sb = StringBuilder() - for (attendee in event.attendees) { - if (first) { - first = false - sb.append(getString(R.string.journal_item_attendees)).append(": ") - } else { - sb.append(", ") + first = true + sb = StringBuilder() + for (alarm in event.alarms) { + if (first) { + first = false + sb.append(getString(R.string.journal_item_reminders)).append(": ") + } else { + sb.append(", ") + } + sb.append(alarm.trigger.value) + } + setTextViewText(view, R.id.reminders, sb.toString()) } - sb.append(attendee.calAddress.toString().replaceFirst("mailto:".toRegex(), "")) } - setTextViewText(view, R.id.attendees, sb.toString()) - - first = true - sb = StringBuilder() - for (alarm in event.alarms) { - if (first) { - first = false - sb.append(getString(R.string.journal_item_reminders)).append(": ") - } else { - sb.append(", ") - } - sb.append(alarm.trigger.value) - } - setTextViewText(view, R.id.reminders, sb.toString()) } } - private inner class LoadContactTask internal constructor(internal var view: View) : AsyncTask() { - - override fun doInBackground(vararg aVoids: Void): Contact? { + private fun loadContactTask(view: View): Future { + return doAsync { + var contact: Contact? = null val reader = StringReader(syncEntry.content) try { - return Contact.fromReader(reader, null)[0] + contact = Contact.fromReader(reader, null)[0] } catch (e: IOException) { e.printStackTrace() } - return null - } + if (contact != null) { + uiThread { + val loader = view.findViewById(R.id.loading_msg) + loader.visibility = View.GONE + val contentContainer = view.findViewById(R.id.content_container) + contentContainer.visibility = View.VISIBLE - override fun onPostExecute(contact: Contact) { - val loader = view.findViewById(R.id.loading_msg) - loader.visibility = View.GONE - val contentContainer = view.findViewById(R.id.content_container) - contentContainer.visibility = View.VISIBLE + val tv = view.findViewById(R.id.display_name) as TextView + tv.text = contact.displayName - val tv = view.findViewById(R.id.display_name) as TextView - tv.text = contact.displayName - - if (contact.group) { - showGroup(contact) - } else { - showContact(contact) + if (contact.group) { + showGroup(contact) + } else { + showContact(contact) + } + } } } + } - private fun showGroup(contact: Contact) { - val mainCard = view.findViewById(R.id.main_card) as ViewGroup - addInfoItem(view.context, mainCard, getString(R.string.journal_item_member_count), null, contact.members.size.toString()) + private fun showGroup(contact: Contact) { + val view = this.view!! - for (member in contact.members) { - addInfoItem(view.context, mainCard, getString(R.string.journal_item_member), null, member) - } + val mainCard = view.findViewById(R.id.main_card) as ViewGroup + + addInfoItem(view.context, mainCard, getString(R.string.journal_item_member_count), null, contact.members.size.toString()) + + for (member in contact.members) { + addInfoItem(view.context, mainCard, getString(R.string.journal_item_member), null, member) + } + } + + + private fun showContact(contact: Contact) { + val view = this.view!! + val mainCard = view.findViewById(R.id.main_card) as ViewGroup + val aboutCard = view.findViewById(R.id.about_card) as ViewGroup + aboutCard.findViewById(R.id.title_container).visibility = View.VISIBLE + + // TEL + for (labeledPhone in contact.phoneNumbers) { + val types = labeledPhone.property.types + val type = if (types.size > 0) types[0].value else null + addInfoItem(view.context, mainCard, getString(R.string.journal_item_phone), type, labeledPhone.property.text) } - - private fun showContact(contact: Contact) { - val mainCard = view.findViewById(R.id.main_card) as ViewGroup - val aboutCard = view.findViewById(R.id.about_card) as ViewGroup - aboutCard.findViewById(R.id.title_container).visibility = View.VISIBLE - - // TEL - for (labeledPhone in contact.phoneNumbers) { - val types = labeledPhone.property.types - val type = if (types.size > 0) types[0].value else null - addInfoItem(view.context, mainCard, getString(R.string.journal_item_phone), type, labeledPhone.property.text) - } - - // EMAIL - for (labeledEmail in contact.emails) { - val types = labeledEmail.property.types - val type = if (types.size > 0) types[0].value else null - addInfoItem(view.context, mainCard, getString(R.string.journal_item_email), type, labeledEmail.property.value) - } - - // ORG, TITLE, ROLE - if (contact.organization != null) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_organization), contact.jobTitle, contact.organization?.values!![0]) - } - if (contact.jobDescription != null) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_job_description), null, contact.jobTitle) - } - - // IMPP - for (labeledImpp in contact.impps) { - addInfoItem(view.context, mainCard, getString(R.string.journal_item_impp), labeledImpp.property.protocol, labeledImpp.property.handle) - } - - // NICKNAME - if (contact.nickName != null && !contact.nickName?.values?.isEmpty()!!) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_nickname), null, contact.nickName?.values!![0]) - } - - // ADR - for (labeledAddress in contact.addresses) { - val types = labeledAddress.property.types - val type = if (types.size > 0) types[0].value else null - addInfoItem(view.context, mainCard, getString(R.string.journal_item_address), type, labeledAddress.property.label) - } - - // NOTE - if (contact.note != null) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_note), null, contact.note) - } - - // URL - for (labeledUrl in contact.urls) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_website), null, labeledUrl.property.value) - } - - // ANNIVERSARY - if (contact.anniversary != null) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_anniversary), null, getDisplayedDate(contact.anniversary?.date, contact.anniversary?.partialDate)) - } - // BDAY - if (contact.birthDay != null) { - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_birthday), null, getDisplayedDate(contact.birthDay?.date, contact.birthDay?.partialDate)) - } - - // RELATED - for (related in contact.relations) { - val types = related.types - val type = if (types.size > 0) types[0].value else null - addInfoItem(view.context, aboutCard, getString(R.string.journal_item_relation), type, related.text) - } - - // PHOTO - // if (contact.photo != null) + // EMAIL + for (labeledEmail in contact.emails) { + val types = labeledEmail.property.types + val type = if (types.size > 0) types[0].value else null + addInfoItem(view.context, mainCard, getString(R.string.journal_item_email), type, labeledEmail.property.value) } + + // ORG, TITLE, ROLE + if (contact.organization != null) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_organization), contact.jobTitle, contact.organization?.values!![0]) + } + if (contact.jobDescription != null) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_job_description), null, contact.jobTitle) + } + + // IMPP + for (labeledImpp in contact.impps) { + addInfoItem(view.context, mainCard, getString(R.string.journal_item_impp), labeledImpp.property.protocol, labeledImpp.property.handle) + } + + // NICKNAME + if (contact.nickName != null && !contact.nickName?.values?.isEmpty()!!) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_nickname), null, contact.nickName?.values!![0]) + } + + // ADR + for (labeledAddress in contact.addresses) { + val types = labeledAddress.property.types + val type = if (types.size > 0) types[0].value else null + addInfoItem(view.context, mainCard, getString(R.string.journal_item_address), type, labeledAddress.property.label) + } + + // NOTE + if (contact.note != null) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_note), null, contact.note) + } + + // URL + for (labeledUrl in contact.urls) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_website), null, labeledUrl.property.value) + } + + // ANNIVERSARY + if (contact.anniversary != null) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_anniversary), null, getDisplayedDate(contact.anniversary?.date, contact.anniversary?.partialDate)) + } + // BDAY + if (contact.birthDay != null) { + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_birthday), null, getDisplayedDate(contact.birthDay?.date, contact.birthDay?.partialDate)) + } + + // RELATED + for (related in contact.relations) { + val types = related.types + val type = if (types.size > 0) types[0].value else null + addInfoItem(view.context, aboutCard, getString(R.string.journal_item_relation), type, related.text) + } + + // PHOTO + // if (contact.photo != null) } private fun getDisplayedDate(date: Date?, partialDate: PartialDate?): String? { diff --git a/app/src/main/java/com/etesync/syncadapter/ui/journalviewer/ListEntriesFragment.kt b/app/src/main/java/com/etesync/syncadapter/ui/journalviewer/ListEntriesFragment.kt index ee778003..c27d07cd 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/journalviewer/ListEntriesFragment.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/journalviewer/ListEntriesFragment.kt @@ -9,7 +9,6 @@ package com.etesync.syncadapter.ui.journalviewer import android.content.Context -import android.os.AsyncTask import android.os.Bundle import android.support.v4.app.ListFragment import android.view.LayoutInflater @@ -25,13 +24,16 @@ import com.etesync.syncadapter.model.* import com.etesync.syncadapter.ui.JournalItemActivity import io.requery.Persistable import io.requery.sql.EntityDataStore +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.uiThread +import java.util.concurrent.Future class ListEntriesFragment : ListFragment(), AdapterView.OnItemClickListener { private lateinit var data: EntityDataStore private lateinit var info: CollectionInfo private var journalEntity: JournalEntity? = null - private var asyncTask: AsyncTask<*, *, *>? = null + private var asyncTask: Future? = null private var emptyTextView: TextView? = null @@ -51,10 +53,26 @@ class ListEntriesFragment : ListFragment(), AdapterView.OnItemClickListener { return view } + fun loadEntries(): List { + journalEntity = JournalModel.Journal.fetch(data, info.getServiceEntity(data), info.uid) + return data.select(EntryEntity::class.java).where(EntryEntity.JOURNAL.eq(journalEntity)).orderBy(EntryEntity.ID.desc()).get().toList() + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - asyncTask = JournalFetch().execute() + asyncTask = doAsync { + val entries = loadEntries() + + uiThread { + val listAdapter = EntriesListAdapter(context!!) + setListAdapter(listAdapter) + + listAdapter.addAll(entries) + + emptyTextView!!.text = getString(R.string.journal_entries_list_empty) + } + } listView.onItemClickListener = this } @@ -89,23 +107,6 @@ class ListEntriesFragment : ListFragment(), AdapterView.OnItemClickListener { } } - private inner class JournalFetch : AsyncTask>() { - - override fun doInBackground(vararg voids: Void): List { - journalEntity = JournalModel.Journal.fetch(data, info.getServiceEntity(data), info.uid) - return data.select(EntryEntity::class.java).where(EntryEntity.JOURNAL.eq(journalEntity)).orderBy(EntryEntity.ID.desc()).get().toList() - } - - override fun onPostExecute(result: List) { - val listAdapter = EntriesListAdapter(context!!) - setListAdapter(listAdapter) - - listAdapter.addAll(result) - - emptyTextView!!.text = getString(R.string.journal_entries_list_empty) - } - } - companion object { protected val EXTRA_COLLECTION_INFO = "collectionInfo"