이제 결과를 받아왔으니

적절하게 꾸며야지


27개의 Todo가 있다.


<!--TODO (1) Add a string stating that an error has occurred-->

strings.xml 부터 error 발생 시 보여줄 message 추가

<resources>
    <string name="app_name">GithubSearch</string>

    <string name="search">Search</string>

    <!--TODO (1) Add a string stating that an error has occurred-->
    <string name="error_message">
        Failed to get results. Please try again.
    </string>
</resources>


<!--TODO (2) Wrap the ScrollView in a FrameLayout-->
<!--TODO (3) Make the width and height of the FrameLayout match_parent-->
activity_main.xml 에 scrollview를 FrameLayout으로 감싸준다.

    <!--TODO (2) Wrap the ScrollView in a FrameLayout-->
    <!--TODO (3) Make the width and height of the FrameLayout match_parent-->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp">
            <TextView
                android:id="@+id/tv_github_search_results_json"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Make a search!"
                android:textSize="18sp" />
        </ScrollView>
    </FrameLayout> 


<!--TODO (4) Add a TextView to display an error message-->
<!--TODO (5) Set the text size to 22sp-->
<!--TODO (6) Give the TextView an id of @+id/tv_error_message_display-->
<!--TODO (7) Set the layout_height and layout_width to wrap_content-->
<!--TODO (8) Add 16dp of padding to the error display -->
<!--TODO (9) Use your strings.xml error message to set the text for the error message-->
<!--TODO (10) Set the visibility of the view to invisible-->
<!--TODO (11) Make this TextView a child of the FrameLayout that you added above-->

error message를 화면에 보여줄 수 있도록 Textview를 추가한다.

        <TextView
            android:id="@+id/tv_error_message_display"
            android:textSize="22sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:text="@string/error_message"
            android:visibility="invisible" /> 


<!--TODO (18) Add a ProgressBar to indicate loading to your users-->
<!--TODO (19) Give the ProgressBar an id of @+id/pb_loading_indicator-->
<!--TODO (20) Set the layout_height and layout_width to 42dp-->
<!--TODO (21) Set the layout_gravity to center-->
<!--TODO (22) Set the visibility of the ProgressBar to invisible-->
<!--TODO (23) Make this ProgressBar a child of the FrameLayout the you added above-->

처리되는 동안 표시 될 Progressbar를 추가한다.

        <ProgressBar
            android:id="@+id/pb_loading_indicator"
            android:layout_height="42dp"
            android:layout_width="42dp"
            android:layout_gravity="center"
            android:visibility="invisible" /> 


MainActivity를 수정한다.

순서상으로는 12(TextView 추가) 후 24(Progressbar 추가) 이나 xml을 먼저 정의 해 놓은 다음 처리했다.

// TODO (12) Create a variable to store a reference to the error message TextView
// TODO (24) Create a ProgressBar variable to store a reference to the ProgressBar

import android.widget.ProgressBar;
...
    // TODO (12) Create a variable to store a reference to the error message TextView
    private TextView mErrorMessageDisplay;
    // TODO (24) Create a ProgressBar variable to store a reference to the ProgressBar
    private ProgressBar mLoadingIndicator; 


// TODO (13) Get a reference to the error TextView using findViewById
// TODO (25) Get a reference to the ProgressBar using findViewById

onCreate method에 xml값과 변수를 매핑시킨다.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSearchBoxEditText = (EditText) findViewById(R.id.et_search_box);
        mUrlDisplayTextView = (TextView) findViewById(R.id.tv_url_display);
        mSearchResultsTextView = (TextView) findViewById(R.id.tv_github_search_results_json);

        // TODO (13) Get a reference to the error TextView using findViewById
        mErrorMessageDisplay = (TextView) findViewById(R.id.tv_error_message_display);
        // TODO (25) Get a reference to the ProgressBar using findViewById
        mLoadingIndicator = (ProgressBar) findViewById(R.id.pb_loading_indicator);
    } 


// TODO (14) Create a method called showJsonDataView to show the data and hide the error
// TODO (15) Create a method called showErrorMessage to show the error and hide the data

jsonData를 보여줄 method 추가, errorMessage를 보여줄 method 추가

    // TODO (14) Create a method called showJsonDataView to show the data and hide the error
    private void showJsonDataView() {
        // First, make sure the error is invisible
        mErrorMessageDisplay.setVisibility(View.INVISIBLE);
        // Then, make sure the JSON data is visible
        mSearchResultsTextView.setVisibility(View.VISIBLE);
    }


    // TODO (15) Create a method called showErrorMessage to show the error and hide the data
    private void showErrorMessage() {
        // First, hide the currently visible data
        mSearchResultsTextView.setVisibility(View.INVISIBLE);
        // Then, show the error
        mErrorMessageDisplay.setVisibility(View.VISIBLE);
    } 


// TODO (16) Call showErrorMessage if the result is null in onPostExecute       
// TODO (17) Call showJsonDataView if we have valid, non-null results

inner class인 GithubQueryTask 의 onPostExecute에 결과를 보여주도록 추가

        @Override
        protected void onPostExecute(String githubSearchResults) {
            if (githubSearchResults != null && !githubSearchResults.equals("")) {
                // TODO (17) Call showJsonDataView if we have valid, non-null results
                showJsonDataView();
                mSearchResultsTextView.setText(githubSearchResults);
            } else {
                // TODO (16) Call showErrorMessage if the result is null in onPostExecute
                showErrorMessage();
            }
        } 


// TODO (26) Override onPreExecute to set the loading indicator to visible

inner class인 GithubQueryTask 의 onPreExecute 재정의(onPostExecute아님)

        // TODO (26) Override onPreExecute to set the loading indicator to visible
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mLoadingIndicator.setVisibility(View.VISIBLE);
        } 


// TODO (27) As soon as the loading is complete, hide the loading indicator

loading이 끝나자마다 indicator를 숨기도록 처리

onPostExecute 의 최종 결과임

    @Override
    protected void onPostExecute(String githubSearchResults) {
        // TODO (27) As soon as the loading is complete, hide the loading indicator
        mLoadingIndicator.setVisibility(View.INVISIBLE);
       
        if (githubSearchResults != null && !githubSearchResults.equals("")) {
            // TODO (17) Call showJsonDataView if we have valid, non-null results
            showJsonDataView();
            mSearchResultsTextView.setText(githubSearchResults);
        } else {
            // TODO (16) Call showErrorMessage if the result is null in onPostExecute
            showErrorMessage();
        }
    } 



728x90

이번에는 동기화를 진행하여 네트워크를 통한 조회결과를 가져오는 부분이다.


// TODO (1) Create a class called GithubQueryTask that extends AsyncTask<URL, Void, String>
// TODO (2) Override the doInBackground method to perform the query. Return the results. (Hint: You've already written the code to perform the query)
// TODO (3) Override onPostExecute to display the results in the TextView

MainActivity 에 inner class로 GithubQueryTask를 추가
GithubQueryTask의 doInBackground method에서 쿼리를 날리고 결과를 받는다.

GithubQueryTask의 onPostExecute method에서 가져온 결과를 TextView에 보여준다.


import android.os.AsyncTask;

...

     // TODO (1) Create a class called GithubQueryTask that extends AsyncTask<URL, Void, String>
    public class GithubQueryTask extends AsyncTask<URL, Void, String> {

        // TODO (2) Override the doInBackground method to perform the query. Return the results. (Hint: You've already written the code to perform the query)
        @Override
        protected String doInBackground(URL... params) {
            URL searchUrl = params[0];
            String githubSearchResults = null;
            try {
                githubSearchResults = NetworkUtils.getResponseFromHttpUrl(searchUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return githubSearchResults;
        }


        // TODO (3) Override onPostExecute to display the results in the TextView
        @Override
        protected void onPostExecute(String githubSearchResults) {
            if (githubSearchResults != null && !githubSearchResults.equals("")) {
                mSearchResultsTextView.setText(githubSearchResults);
            }
        }
    }


// TODO (4) Create a new GithubQueryTask and call its execute method, passing in the url to query

makeGithubSearchQuery 에서 쿼리를 날릴 때 변경한 GithubQueryTask를 사용하도록 한다.(기존것은 주석처리)

//        String githubSearchResults = null;
//        try {
//            githubSearchResults = NetworkUtils.getResponseFromHttpUrl(githubSearchUrl);
//            mSearchResultsTextView.setText(githubSearchResults);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        // TODO (4) Create a new GithubQueryTask and call its execute method, passing in the url to query
        new GithubQueryTask().execute(githubSearchUrl); 


App을 실행시켜서 'queen'이라는 단어로 쿼리를 날리면

먼저 url을 화면에 보여주고 잠시 후에 쿼리 결과가 나타난다.


네트워크를 통한 요청을 했을 때 응답을 받을 때까지 대기하도록 해야하기 때문임.

응답받기전에 결과를 처리하려고 한 T02.04는 에러가 날 수 밖에 없음.

728x90

이번에는 네트워크를 통하여

github 검색을 하는 것인데


이번 예제의 실행결과는 무조건 실패다.

solution project를 실행시켜도 app 에러가 난다.

다음예제인 T02.05에서 해결이 되는 것이니 TODO 설정을 제대로 한 뒤에 다음 강좌로 넘어가기 바란다.



<!--TODO (1) Add the INTERNET permission-->

AndroidManifest.xml 에 internet을 사용하는 권한 추가


// TODO (2) Call getResponseFromHttpUrl and display the results in mSearchResultsTextView
// TODO (3) Surround the call to getResponseFromHttpUrl with a try / catch block to catch an IOException

MainActivity의 makeGithubSearchQuery method 에서 쿼리조회를 하고 결과를 가져온다.

network을 사용할 때 오류가 날 수 있으니 IOException으로 감싸준다.

import java.io.IOException;

...

     private void makeGithubSearchQuery() {
        String githubQuery = mSearchBoxEditText.getText().toString();
        URL githubSearchUrl = NetworkUtils.buildUrl(githubQuery);
        mUrlDisplayTextView.setText(githubSearchUrl.toString());

        // TODO (2) Call getResponseFromHttpUrl and display the results in mSearchResultsTextView
        // TODO (3) Surround the call to getResponseFromHttpUrl with a try / catch block to catch an IOException
        String githubSearchResults = null;
        try {
            githubSearchResults = NetworkUtils.getResponseFromHttpUrl(githubSearchUrl);
            mSearchResultsTextView.setText(githubSearchResults);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


---

실행시켜보면 앱이 바로 종료된다.

Lotcat에서 확인해보면

 2019-01-13 13:22:41.295 3960-3960/com.example.android.datafrominternet E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.datafrominternet, PID: 3960
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1448)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
        at java.net.InetAddress.getAllByName(InetAddress.java:787)
        at com.android.okhttp.Dns$1.lookup(Dns.java:39)
        at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
        at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:407)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:244)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(Unknown Source:0)
        at com.example.android.datafrominternet.utilities.NetworkUtils.getResponseFromHttpUrl(NetworkUtils.java:76)
        at com.example.android.datafrominternet.MainActivity.makeGithubSearchQuery(MainActivity.java:63)
        at com.example.android.datafrominternet.MainActivity.onOptionsItemSelected(MainActivity.java:80)
        at android.app.Activity.onMenuItemSelected(Activity.java:3435)


로그는 거꾸 읽어가는 것임.

먼저 onMenuItemSelect에서 버튼클릭이 있어났고

onOptionsItemSelectd 에서 어떤버튼인지 확인한 다음.

makeGithubsearchQuery method 에서 NetworkUtils를 호출한다.

그 와중에 getInputStream 에서 최종 에러가 난 것이다.


위 에러가 나면 다음강좌로 넘어간다.

network 사용시에는 동기화라는 것이 필요한데 설정이 되어있지 않아서 발생하는 것임.

728x90

이번에는 network 을 살펴본다



// TODO (1) Fill in this method to build the proper Github query URL

1. buildUrl method를 완성시킨다.

utilities 라는 package를 새로 생성.  NetworkUtils 라는 class도 생성

AS-IS : 껍데기만 있음

    public static URL buildUrl(String githubSearchQuery) {
        // TODO (1) Fill in this method to build the proper Github query URL
        return null;
    } 

-> TO-BE : 동작

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

import java.net.MalformedURLException;
import java.net.URL;

final static String GITHUB_BASE_URL = "https://api.github.com/search/repositories";

final static String PARAM_QUERY = "q";

final static String PARAM_SORT = "sort";

final static String sortBy = "stars";

    public static URL buildUrl(String githubSearchQuery) {
        // COMPLETED (1) Fill in this method to build the proper Github query URL
        Uri builtUri = Uri.parse(GITHUB_BASE_URL).buildUpon()
                .appendQueryParameter(PARAM_QUERY, githubSearchQuery)
                .appendQueryParameter(PARAM_SORT, sortBy)
                .build();

        URL url = null;
        try {
            url = new URL(builtUri.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return url;
    } 


// TODO (2) Create a method called makeGithubSearchQuery
// TODO (3) Within this method, build the URL with the text from the EditText and set the built URL to the TextView
MainActivity 에서 method 추가한 뒤에 내용을 넣는다.

사용자가 입력한 EditText의 내용으로 github에 조회할 전체경로를 TextView에 보여준다.

    private void makeGithubSearchQuery() {
        String githubQuery = mSearchBoxEditText.getText().toString();
        URL githubSearchUrl = NetworkUtils.buildUrl(githubQuery);
        mUrlDisplayTextView.setText(githubSearchUrl.toString());
    } 


// TODO (4) Remove the Toast message when the search menu item is clicked
// TODO (5) Call makeGithubSearchQuery when the search menu item is clicked

클릭버튼 동작유무를 확인하기 위한 ToastMessage를 제거하고

makeGithubSearchQuery를 호출한다.

@Override
public boolean onOptionsItemSelected(MenuItem item){
    int itemThatWasClickedId = item.getItemId();

    if (itemThatWasClickedId == R.id.action_search) {
        // COMPLETED (4) Remove the Toast message when... is clicked
//            Context context = MainActivity.this;
//            String textToShow = "Search clicked";
//            Toast.makeText(context, textToShow, Toast.LENGTH_SHORT).show();


        // COMPLETED (5) Call makeGithubSearchQuery when... clicked
        makeGithubSearchQuery();

        return true;
    } 


앱을 실행시켜보면

queen이라는 단어 입력 후 Search버큰을 클릭하면

github로 날릴 조회쿼리가 표시된다.

아직 실제로 쿼리를 날린것이 아니므로 결과는 안나온다




728x90
BLOG main image
"그게 뭐 어쨌다는 거냐?" 늘 누가 나에게 나에대한 말을할 때면 이말을 기억해라. by nobang

카테고리

nobang이야기 (1932)
Life With Gopro (7)
Life With Mini (79)
Diary (971)
너 그거 아니(do you know) (162)
난 그래 (158)
Study (290)
속지말자 (10)
Project (34)
Poem (15)
Song (0)
Photo (113)
낙서장 (45)
일정 (0)
C.A.P.i (2)
PodCast (0)
nobang (27)
고한친구들 (4)
recieve (0)
History (0)
android_app (2)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :