【发布时间】:2018-02-03 07:35:30
【问题描述】:
我正在学习 Android 开发并创建一个应用程序,该应用程序在单击按钮时调用 REST 服务,该服务会返回电影中的名言。此报价将显示在屏幕上(在 TextView 上)。
我已将用户权限添加到清单文件中:
<uses-permission android:name="android.permission.INTERNET" />
这是我的 MainActivity.java 代码
public class MainActivity extends AppCompatActivity {
private static final String LOGTAG = "info";
private static final String QUOTES_API = "https://andruxnet-random-famous-quotes.p.mashape.com/?cat=movies&count=1";
private static final String MASHAPE_KEY = "this-my-api-key";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button newQuoteBtn = (Button) findViewById(R.id.quotesBtn);
newQuoteBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
String quote = getQuote();
Log.i(LOGTAG, quote);
//the quote will be then shown on the text view
}
});
}
private String getQuote() {
try {
URL quotesURL = new URL(QUOTES_API);
HttpsURLConnection conn = (HttpsURLConnection) quotesURL.openConnection();
conn.setRequestProperty("X-Mashape-Key", MASHAPE_KEY);
conn.setRequestProperty("Accept", "application/json");
if(conn.getResponseCode() == 200) {
InputStream inputStream = conn.getInputStream();
InputStreamReader isReader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader buffReader = new BufferedReader(isReader);
StringBuffer json = new StringBuffer(1024);
String tmp="";
while((tmp=buffReader.readLine())!=null) {
json.append(tmp).append("\n");
}
buffReader.close();
JSONObject data = new JSONObject(json.toString());
Log.i(LOGTAG, data.getString("quote"));
return data.getString("quote");
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
但是,当我单击模拟器应用程序中的按钮时,什么也没有发生,它只是将以下消息添加到 logcat
android.os.NetworkOnMainThreadException
根据我的阅读,我无法在主线程上执行网络操作,这就是我们必须使用 AsyncTask 的原因。我知道我需要创建一个扩展 AsyncTask 的新类,但我仍然对一些事情感到困惑:
Q1) 新类会是 MainActivity.java 的内部类,还是也可以是单独的类文件?
Q2) class GetQuotesClass extends AsyncTask<?, ?, ?> 的参数是什么,我只发送 <void, void, void> 吗?
Q3) 我如何从我的按钮点击中调用它?我应该只做new GetQuotesClass().execute()吗?
我还在另一个堆栈溢出线程中阅读了以下评论
AsyncTask 不应该用于网络活动,因为它是绑定的 到活动,但不是活动生命周期。旋转设备 运行此任务将导致异常并使您的应用程序崩溃。 使用 IntentService 来代替 sqlite 数据库中的数据
我很困惑该做什么以及如何去做。任何帮助将不胜感激。
谢谢。
【问题讨论】:
-
您可以使用 Volley 或 Retrofit 等第三方库通过 REST API 获取数据。它们都在单独的线程上异步工作,更容易实现
-
是的,这是一种方式,但我现在不想与第三方库打交道,因为我已经开始学习 Android。所以我正在寻找一些内部解决方案。
标签: java android multithreading android-asynctask