我正在尝试用RxAndroid observables替换我的AsycTask,但我实现了这一点,但我相信这不是使用RxAndroid的正确方法,我是否可以寻求指导?
我想要实现的是每次用户点击“ lookupButton”以在牛津API中检查所需工作,然后在屏幕上显示其定义时发出一个网络请求,这是我的代码:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
// ButterKnife
ButterKnife.bind(this)
coordinatorLayout.setOnTouchListener(this)
mainInput.editText?.setOnEditorActionListener(this)
// set up Rx
RxView.clicks(lookupButton).map {
lookupButtonClick()
}.subscribe()
}
fun lookupButtonClick() {
// Check internet connection
if(checkConnection() != null) {
var tempText = ""
// Get user input
tempText = mainInput.editText?.text.toString()
Observable.just(tempText)
.subscribeOn(Schedulers.io())
.map{
lookupFun(tempText)
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object: Observer<String> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: String) {
if (t == "404") { // word not found error
Snackbar.make(coordinatorLayout, resources.getText(R.string.word_not_found_error), Snackbar.LENGTH_SHORT).show()
} else {
val resultJSON = JSONObject(t)
// Get "definition" field from JSON (ugly way)
val JSON_results = resultJSON.getJSONArray("results")
val JSON_lexical = JSON_results.getJSONObject(0).getJSONArray("lexicalEntries")
val JSON_entries = JSON_lexical.getJSONObject(0).getJSONArray("entries")
val JSON_senses = JSON_entries.getJSONObject(0).getJSONArray("senses")
val JSON_definitions = JSON_senses.getJSONObject(0).getJSONArray("definitions")
Log.i("JSON", JSON_definitions.getString(0))
var tempString: String = ""
for (i in 0..(JSON_definitions.length() - 1)) {
tempString += "${i + 1}: ${JSON_definitions.getString(i)}\n"
}
definitionTextView.text = tempString
print(t)
}
}
override fun onError(e: Throwable) {
Snackbar.make(coordinatorLayout, resources.getText(R.string.server_error), Snackbar.LENGTH_SHORT).show()
}
})
} else {
Snackbar.make(coordinatorLayout, resources.getText(R.string.internet_error), Snackbar.LENGTH_SHORT).show()
}
}
fun lookupFun(s: String) : String {
// local vals
val oxfordAppID: String = "d152ef74"
val oxfordAppKEY: String = "0f2153750b709f4ffabb848a8eda2448"
val oxfordAppBASE_URL: String = "https://od-api.oxforddictionaries.com/api/v1/entries/"
val oxfordAppDestLang: String = "es"
val oxfordAppSourceLang: String = "en"
Log.i("ASYNC", "Step 1")
// compose URL with desired word
val url: URL = URL(oxfordAppBASE_URL + oxfordAppSourceLang +
"/" + s.toLowerCase())
Log.i("ASYNC", "Step 2, URL: " + url)
// Open URL connection
val urlConnection: HttpURLConnection = url.openConnection() as HttpURLConnection
// Set URL connection properties
urlConnection.requestMethod = "GET"
urlConnection.setRequestProperty("Accept", "application/json")
urlConnection.setRequestProperty("app_id", oxfordAppID)
urlConnection.setRequestProperty("app_key", oxfordAppKEY)
Log.i("ASYNC", "Response code: " + urlConnection.responseCode)
// check for 404 error code
if(urlConnection.responseCode == 404) // word not found
return Integer.toString(urlConnection.responseCode)
val reader = BufferedReader(InputStreamReader(urlConnection.inputStream))
val sBuilder = StringBuilder()
var line: String? = null
do {
line = reader.readLine()
sBuilder.append(line + "\n")
} while (line != null)
return sBuilder.toString()
}
我相信我应该从我的按钮创建一个Observable,然后观察它是否被单击(如果是)->在Schedulers.io线程上启动连接,但是我不清楚如何实现此目的。