Android 我应该使用 AsyncTask 还是 IntentService 进行 REST API 调用? [复制]
Posted
技术标签:
【中文标题】Android 我应该使用 AsyncTask 还是 IntentService 进行 REST API 调用? [复制]【英文标题】:Should I use AsyncTask or IntentService for making a REST API call? [duplicate] 【发布时间】: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 数据库中的数据
我很困惑该做什么以及如何去做。任何帮助将不胜感激。
谢谢。
【问题讨论】:
看看这个问题***.com/questions/29339565/… 也发现了这个:youtube.com/watch?v=xXkjfnhqRGI 您可以使用 Volley 或 Retrofit 等第三方库通过 REST API 获取数据。它们都在单独的线程上异步工作,更容易实现 是的,这是一种方式,但我现在不想与第三方库打交道,因为我已经开始学习 Android。所以我正在寻找一些内部解决方案。 【参考方案1】:好的,我知道怎么做,这里是代码(减去 API 密钥和其他东西)
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 = "myapikey";
TextView quotesTextView, quotesSourceTextView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button newQuoteBtn = (Button) findViewById(R.id.quotesBtn);
quotesTextView = (TextView) findViewById(R.id.quotesText);
quotesSourceTextView = (TextView) findViewById(R.id.quotesSourceText);
newQuoteBtn.setOnClickListener(new OnClickListener()
@Override
public void onClick(View view)
new GetQuote().execute();
);
private class GetQuote extends AsyncTask<Void, Void, Void>
private String quote, quoteSource;
@Override
protected Void doInBackground(Void... voids)
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"));
quote = data.getString("quote");
quoteSource = data.getString("author");
else
quote = "Response code: " + conn.getResponseCode();
quoteSource = "Mashape";
catch (Exception e)
e.printStackTrace();
quote = e.getMessage();
quoteSource = "Exception Class";
return null;
@Override
protected void onPostExecute(Void aVoid)
quotesTextView.setText(quote);
quotesSourceTextView.setText(quoteSource);
super.onPostExecute(aVoid);
【讨论】:
您决定使用 AsyncTask 来获取网络请求,尽管 AsyncTask 存在已知的缺点? 我重写了我的代码,现在我正在使用 Volley。 Volley 是否完美地满足了您的需求,或者您是否也考虑过使用 Retrofit? Volley 符合我的需求。这是一项非常好的服务。以上是关于Android 我应该使用 AsyncTask 还是 IntentService 进行 REST API 调用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
Android 我应该使用 AsyncTask 还是 IntentService 进行 REST API 调用? [复制]
Android最好使用AsyncTask、Service或其他