Kotlin是功能非常強大的編程語言,在java以及多種語言的基礎(chǔ)上巫击,去掉了冗余代碼,方便開發(fā)者用較少的模板編寫更多的代碼精续。尤其是在Android開發(fā)中坝锰。除了編程語言自身和它的類之外,Kotlin還為已有的Java類提供一組好用的擴展重付。這個例子是請求API和下載結(jié)果的方法顷级,通過對比我們可以更加直觀了解kotlin的藝術(shù)。
API請求:Java 與 Kotlin對比
使用android studio的kotlin插件确垫,可以很方便的把java代碼轉(zhuǎn)換成kotlin代碼弓颈,通過兩種語言進行對比,看看堅持使用Java會錯過什么删掀。
下面是java代碼:
public String url(String apiUrl) {
try {
URL url = null;
url = new URL(apiUrl);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
result = buffer.toString();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
Log.e("Request", "Error ", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("Request", "Error closing stream", e);
}
}
}
return null;
}
下面是kotlin代碼
fun url(apiUrl: String): String? {
return URL(apiUrl).readText()
}
沒有看錯翔冀,就是一行,是不是很神奇爬迟,Kotlin標準庫為URL類提供了擴展函數(shù)橘蜜,避免我們編寫所有代碼菊匿。
對于大量的響應(yīng)付呕,不建議使用這個函數(shù)计福,但是在大多數(shù)情況下,它是足夠了徽职。如果不這樣象颖,還有許多其他有趣的擴展函數(shù),如:BufferedReader.forEachLine()姆钉,它產(chǎn)生行Sequence说订,我們可以用它們中任何一個〕逼浚或是陶冷,可以通過BufferedReader.lineSequence()得到原始的Sequence<String>。這時毯辅,你能夠使用Sequence進行各種操作埂伦,如:過濾、排序思恐、映射等等沾谜。
異步請求
主線程是負責(zé)UI呈現(xiàn)和交互的,我們不應(yīng)該因其它運行時間長的任務(wù)阻塞它胀莹,這將會影響UI性能基跑。在HTTP請求情況下, Android SDK甚至通過拋出一個異常來阻止我們這么做描焰。在Android典型的解決方案是使用AsyncTask
媳否。AsyncTask有一個doInBackground抽象方法,使得方法在另個線程中執(zhí)行荆秦。
java例子
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.tv_title);
textView.setText("hello");
task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
return requestFromServer("<api call>");
}
@Override
protected void onPostExecute(String s) {
if (!isFinishing() && !isCancelled()) {
Log.d("Request", s);
Toast.makeText(MainActivity2.this, "Request performed", Toast.LENGTH_LONG).show();
}
}
};
}
@Override
protected void onDestroy() {
super.onDestroy();
if (task != null) {
task.cancel(true);
task = null;
}
}
private String requestFromServer(String s) {
return s;
}
這實在不清晰也不直觀逆日。學(xué)習(xí)Kotlin開發(fā)時,我們不能漏掉Anko庫萄凤。它主要目的是提供DSL方式用代碼來創(chuàng)建布局室抽,而不是用XML。我實際使用過XML靡努,所以我現(xiàn)在不使用它了坪圾,但是它還是包括一整套非常有用的特性。特別對異步任務(wù)有些小的DSL惑朦。
Kotlin代碼
val result = URL("<api call>").readText()
uiThread {
Log.d("Request", result)
longToast("Request performed")
}
}
實際上兽泄,你有async函數(shù),它將在另一個線程中執(zhí)行代碼漾月,并由uiThread
給出返回主線的機會病梢。async是Context的擴展函數(shù)實現(xiàn),且使用它弱應(yīng)用,所以不會阻止GC釋放內(nèi)存蜓陌。
uiThread
優(yōu)勢的方面是它依據(jù)使用類觅彰,以用不同的方式來實現(xiàn)。如果我們從Activity中調(diào)用它钮热,假設(shè)actiivity.isFinishing()
返回true填抬,uiThread代碼是不會執(zhí)行的,并且在此情況下不會崩潰隧期。
假設(shè)你要用future飒责,Async返回Java Future。如果你需要返回future結(jié)果仆潮,就可以用asyncResult宏蛉。
你還能夠用你自己的執(zhí)行器:
doAsync(executor) {
// Some task
}