The Github Repo Search app searches for a GitHub repository by name. The URL you'll use to get search information will be something like the URL below, which searches for repositories containing the word android and sorts by the number of stars the repo has:
https://api.github.com/search/repositories?q=android&sort=stars
Which returns information in JSON. We'll be going over how to make sense of this returned JSON, parse it and display it in your app during this lesson. We'll also cover how to connect to the internet and download data. Let's get started!
The code for this app can be found in the Lesson02-GitHub-Repo-Search folder of the Toy App Repository.
Exercise Code:
Exercise:
Exercise Code:
Exercise:
main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- TO DO -->
</menu>
<item
android:id="@+id/action_search"
android:orderInCategory="1"
app:showAsAction="ifRoom"
android:title="@string/search"/>
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
// Return true to display your menu
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemThatWasClickedId = item.getItemId();
if (itemThatWasClickedId == R.id.action_search) {
Context context = MainActivity.this;
String textToShow = "Search clicked";
Toast.makeText(context, textToShow, Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
Build the Url that will be used to query Github and display it when the Search button is pressed.
Exercise Code:
Exercise:
public static URL buildUrl(String githubSearchQuery) {
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;
}
private void makeGithubSearchQuery() {
String githubQuery = mSearchBoxEditText.getText().toString();
URL githubSearchUrl = NetworkUtils.buildUrl(githubQuery);
mUrlDisplayTextView.setText(githubSearchUrl.toString());
}
Follow the TODOS. But it will crash when you run it.
Exercise Code:
Exercise:
<uses-permission android:name="android.permission.INTERNET" />
String githubSearchResults = null;
try {
githubSearchResults = NetworkUtils.getResponseFromHttpUrl(githubSearchUrl);
} catch (IOException e) {
e.printStackTrace();
}
mSearchResultsTextView.setText(githubSearchResults);
"When an application component starts and the application does not have any other components running, the Android system starts a new Linux process for the application with a single thread of execution. By default, all components of the same application run in the same process and thread (called the "main" thread). If an application component starts and there already exists a process for that application (because another component from the application exists), then the component is started within that process and uses the same thread of execution. However, you can arrange for different components in your application to run in separate processes, and you can create additional threads for any process."
Check Processes and threads overview for more details how the processes works.
Android AsyncTask
going to do background operation on background thread and update on main thread. In android we can't directly touch background thread to main thread in android development. asynctask helps us to make communication between background thread to main thread.
Methods of AsyncTask
onPreExecute()
− Before doing background operation we should show something on screen like progressbar or any animation to the user. We can directly communicate background operations using doInBackground() but for best practice, we should call all asyncTask methods .doInBackground(Params)
− In this method we have to do background operation on the background thread. Operations in this method should not touch on any mainthread activities or fragments.onProgressUpdate(Progress...)
− While doing background operations, if you want to update some information on UI, we can use this method.onPostExecute(Result)
− In this method we can update the ui of background operation result.Generic Types in Async Task
TypeOfVarArgParams
− It contains information about what type of params used for execution.ProgressValue
− It contains information about progress units. While doing background operation we can update information on the ui using onProgressUpdate().ResultValue
−It contains information about the result type.Exercise Code:
Exercise:
public class GithubQueryTask extends AsyncTask<URL, Void, String> {
}
@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;
}
@Override
protected void onPostExecute(String githubSearchResults) {
if (githubSearchResults != null && !githubSearchResults.equals("")) {
mSearchResultsTextView.setText(githubSearchResults);
}
}
new GithubQueryTask().execute(githubSearchUrl);
Comment out the
<uses-permission android:name="android.permission.INTERNET" />
statement in the AndroidManifest.xml
and then run the app. Make a search in the app, and then look in the Android Monitor logcat.
QUESTION
In the Android Monitor logcat, what error do you see when the app tries to connect to the Internet?
Exercise Code:
Exercise:
<string name="error_message">
Failed to get results. Please try again.
</string>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<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" />
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);
}
private void showErrorMessage() {
// First, hide the currently visible data
mSearchResultsTextView.setVisibility(View.INVISIBLE);
// Then, show the error
mErrorMessageDisplay.setVisibility(View.VISIBLE);
}
<ProgressBar
android:id="@+id/pb_loading_indicator"
android:layout_height="42dp"
android:layout_width="42dp"
android:layout_gravity="center"
android:visibility="invisible" />
JSON
stands for JavaScript Object Notation.It is an independent data exchange format and is the best alternative for XML
. This chapter explains how to parse the JSON
file and extract necessary information from it.
Android provides four different classes to manipulate JSON
data. These classes are JSONArray
, JSONObject
, JSONStringer
and JSONTokenizer
.
Exercise Code:
In this Exercise, you will get to apply what you've learned on Sunshine to add an async task and permissions to load weather data.
Exercise Code:
Look at your TODOs. This is going to look a lot like what we did to add that menu to the Github query app earlier.
Exercise Code:
In this Exercise, you will get to apply what you've learned about adding polish to Sunshine.
Add code and views to display an error message for a failed data retrieval, and loading indicators for loading data.