2017-08-25 79 views
1

我學習Android開發和創造其上按一下按鈕,從電影返回名言調用REST服務的應用程序。該報價將顯示在屏幕上(在TextView上)。Android應該使用AsyncTask還是IntentService來進行REST API調用?

我已經加入了用戶權限清單文件:

<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>?請問class GetQuotesClass extends AsyncTask<?, ?, ?>的參數是什麼?我只是發送<void, void, void>

Q3)我如何把它從我的按鈕點擊?我應該做new GetQuotesClass().execute()

我也看了在另一個堆棧溢出線程

的AsyncTask不應該被用於網絡活動如下評論,因爲它綁 的活動,但不是活動的生命週期。在此任務正在運行時旋轉設備 將導致異常並導致應用程序崩潰。 使用IntentService在sqlite數據庫中刪除數據而不是

我很困惑該怎麼做以及如何去做。任何幫助都感激不盡。

謝謝。

+1

看看這個問題https://stackoverflow.com/questions/29339565 /調用-REST的API-從-AN-Android的應用程序 – amirouche

+0

發現這個還有:https://www.youtube.com/watch?v=xXkjfnhqRGI – codeinprogress

+0

你可以使用第三方的庫,例如排球或通過改造來獲取數據REST API。他們都在一個單獨的線程,更容易異步工作落實 –

回答

0

OK,我發現瞭如何做到這一點,這裏是代碼(減去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); 
     } 
    } 

} 
+0

您決定使用的AsyncTask用於獲取網絡請求,儘管的AsyncTask已知的缺點? –

+1

我重寫了我的代碼,現在我正在使用Volley。 – codeinprogress

+0

Volley是否完全滿足您的需求,或者您是否考慮過使用Retrofit? –

相關問題