2017-08-25 3 views
1

私はAndroid開発を学んでおり、ムービーから有名な見積もりを返すボタンクリックでRESTサービスを呼び出すアプリケーションを作成しています。この見積もりは画面(TextView)に表示されます。AndroidはREST API呼び出しを行うためにAsyncTaskまたはIntentServiceを使用する必要がありますか?

私は、マニフェストファイルにユーザー権限を追加しました:

<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は、アクティビティのライフサイクルそれは活動に を結び付けているため、ネットワーク活動のために使用さではなく、するべきではありません。このタスクを実行しているデバイス を回転させると、例外が発生し、アプリがクラッシュします。 は、私が何をすべきか混乱していますし、どのようにそれを行うには代わりのsqliteデータベース内のデータをドロップIntentService

を使用してください。どんな助けでも大歓迎です。

ありがとうございました。

+1

は、この質問について見てみましょうhttps://stackoverflow.com/questions/29339565 /呼び出し中の残りのアンドロイドアプリ – amirouche

+0

これも見つかった:https://www.youtube.com/watch?v=xXkjfnhqRGI – codeinprogress

+0

VolleyやRetrofitのようなサードパーティのライブラリを使って、 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を使用することを検討しましたか? –

関連する問題