Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Neil Quinn
768 PointsDebugging Error
I have this error when debugging my app: The JAR file C:\sdk\platforms\android-19\android.jar has no source attachment. You can attach the source by clicking attach source below
When I try to attach the file in the directory it won't let me?
Any help would be much appreciated.
9 Answers
Ben Jakuben
Treehouse TeacherI wish I had a complete answer for you, but I don't. I've seen this before and still can't explain it, though I do have a workaround. It seems there is some sort of issue with the AsyncTask posting back to the main thread and trying to update the user interface. This is the trouble with asynchronous processing - there are sometimes weird issues with timing.
I tried moving your async task execution to the onViewCreated() method instead but that did not make a difference. The workaround is to simply insert a log statement somewhere before the data is adapted, like this:
Log.i(TAG, "Adapting data for list...");
SimpleAdapter adapter = new SimpleAdapter(getActivity(), blogPosts, android.R.layout.simple_list_item_2, keys, ids);
Something about that forces the system to continue processing normally. It's as if some important channel is closed off and ready instead of being open and unavailable for the SimpleAdapter. I really don't know at this point. :-/
Hope this gets you going again, at least!
Ben Jakuben
Treehouse TeacherThis is okay to ignore, but it's also fixable. :)
The android.jar file is the source code for the actual Android system. Because it's open source, you can debug into it if you have the appropriate files downloaded. Mine is set up that way, but it's been a while since I did it. I think you just need to get the Android source code from the AOSP site: https://source.android.com/
Some other things to try: http://stackoverflow.com/questions/14648788/debugging-into-android-source
That said, I usually skip the Android classes or sever this link within Eclipse. :)
Neil Quinn
768 PointsWell I think I could be wrong in what's forcing my app to quit then. Anytime I run the app it unexpectedly quits.
Here is the logcat errors:
03-19 19:22:27.653: E/AndroidRuntime(1269): FATAL EXCEPTION: main
03-19 19:22:27.653: E/AndroidRuntime(1269): java.lang.NullPointerException
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.widget.SimpleAdapter.<init>(SimpleAdapter.java:85)
03-19 19:22:27.653: E/AndroidRuntime(1269): at com.teamtreehouse.ribbit.NewsFragment.handleBlogResponse(NewsFragment.java:135)
03-19 19:22:27.653: E/AndroidRuntime(1269): at com.teamtreehouse.ribbit.NewsFragment$GetBlogPostsTask.onPostExecute(NewsFragment.java:200)
03-19 19:22:27.653: E/AndroidRuntime(1269): at com.teamtreehouse.ribbit.NewsFragment$GetBlogPostsTask.onPostExecute(NewsFragment.java:1)
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.os.AsyncTask.finish(AsyncTask.java:631)
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.os.Handler.dispatchMessage(Handler.java:99)
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.os.Looper.loop(Looper.java:137)
03-19 19:22:27.653: E/AndroidRuntime(1269): at android.app.ActivityThread.main(ActivityThread.java:5103)
03-19 19:22:27.653: E/AndroidRuntime(1269): at java.lang.reflect.Method.invokeNative(Native Method)
03-19 19:22:27.653: E/AndroidRuntime(1269): at java.lang.reflect.Method.invoke(Method.java:525)
03-19 19:22:27.653: E/AndroidRuntime(1269): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-19 19:22:27.653: E/AndroidRuntime(1269): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-19 19:22:27.653: E/AndroidRuntime(1269): at dalvik.system.NativeStart.main(Native Method)
Ben Jakuben
Treehouse TeacherSo let's take a look at this exception. It says the NullPointerException is occurring at line 135 of your NewsFragment. The exception is being thrown in the SimpleAdapter class, but that means something isn't right with how you're using it in the NewsFragment. Post all your NewsFragment code in here and perhaps we can troubleshoot it, starting with line 135.
Neil Quinn
768 Pointspackage com.teamtreehouse.ribbit;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class NewsFragment extends ListFragment{
public static final int NUMBER_OF_POSTS = 10;
public static final String TAG = NewsFragment.class.getSimpleName();
protected JSONObject mBlogData;
protected ProgressBar mProgressBar;
private final String KEY_TITLE = "title";
private final String KEY_DATE = "date";
private final String KEY_THUMBNAIL = "thumbnail";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_news_list,
container, false);
mProgressBar = (ProgressBar) rootView.findViewById(R.id.progressBar1);
if(NetworkIsAvailable()) {
mProgressBar.setVisibility(View.VISIBLE);
GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
getBlogPostsTask.execute();
}
else {
Toast.makeText(getActivity(), "Network is unavailable!", Toast.LENGTH_LONG).show();
}
//String message = getString(R.string.no_items);
//Toast.makeText(this, message, Toast.LENGTH_LONG).show();
return rootView;
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
try {
JSONArray jsonPosts = mBlogData.getJSONArray("posts");
JSONObject jsonPost = jsonPosts.getJSONObject(position);
String blogUrl = jsonPost.getString("url");
Intent intent = new Intent(getActivity(),BlogWebViewActivity.class);
intent.setData(Uri.parse(blogUrl));
startActivity(intent);
}
catch (JSONException e) {
logException(e);
}
}
private void logException(Exception e) {
Log.e(TAG, "Exception caught!", e);
}
private boolean NetworkIsAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if(networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
public void handleBlogResponse() {
mProgressBar.setVisibility(View.INVISIBLE);
if (mBlogData == null) {
updateDisplayForError();
}
else {
try {
JSONArray jsonPosts = mBlogData.getJSONArray("posts");
ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < jsonPosts.length(); i++) {
JSONObject post = jsonPosts.getJSONObject(i);
String title = post.getString(KEY_TITLE);
title = Html.fromHtml(title).toString();
String date = post.getString(KEY_DATE);
date = Html.fromHtml(date).toString();
String thumbnail = post.getString(KEY_THUMBNAIL);
thumbnail = Html.fromHtml(thumbnail).toString();
HashMap<String, String> blogPost = new HashMap<String, String>();
blogPost.put(KEY_TITLE, title);
blogPost.put(KEY_DATE, date);
blogPost.put(KEY_THUMBNAIL, thumbnail);
blogPosts.add(blogPost);
}
String[] keys = { KEY_TITLE, KEY_DATE, KEY_THUMBNAIL };
int[] ids = { android.R.id.text1, android.R.id.text2 };
SimpleAdapter adapter = new SimpleAdapter(getActivity(), blogPosts, android.R.layout.simple_list_item_2, keys, ids);
setListAdapter(adapter);
} catch (JSONException e) {
logException(e);
}
}
}
private void updateDisplayForError() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getString(R.string.error_title));
builder.setMessage(getString(R.string.error_message));
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.create();
dialog.show();
TextView emptyTextView = (TextView) getListView().getEmptyView();
emptyTextView.setText(getString(R.string.no_items));
}
private class GetBlogPostsTask extends AsyncTask<Object, Void, JSONObject> {
@Override
protected JSONObject doInBackground(Object... params) {
int responseCode = -1;
JSONObject jsonResponse = null;
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.ilovelimerick.ie/?json=1&count=10");
try {
HttpResponse response = client.execute(httpget);
StatusLine statusLine = response.getStatusLine();
responseCode = statusLine.getStatusCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(content));
String line;
while((line = reader.readLine()) != null){
builder.append(line);
}
jsonResponse = new JSONObject(builder.toString());
}
else {
Log.i(TAG, String.format("Unsuccessful HTTP response code: %d", responseCode));
}
}
catch (JSONException e) {
logException(e);
}
catch (Exception e) {
logException(e);
}
return jsonResponse;
}
@Override
protected void onPostExecute(JSONObject result) {
mBlogData = result;
handleBlogResponse();
}
}
}
Ben Jakuben
Treehouse TeacherIn your editor, which line corresponds to line 135? Or include every single line from the file (including the package and import statements) and I can paste it all in my own editor.
Ben Jakuben
Treehouse TeacherMy guess is that the blogPosts variable isn't getting set correctly. Can you add a breakpoint and use the debugger to look at that variable?
Neil Quinn
768 Pointssorry, my mistake.
SimpleAdapter adapter = new SimpleAdapter(getActivity(), blogPosts, android.R.layout.simple_list_item_2, keys, ids);
I also added all the lines to NewsFragment.
Neil Quinn
768 Points03-19 20:25:23.001: E/eglCodecCommon(1432): writeFully: failed: Broken pipe
Also I'm now getting this line in the logcat, I don't think this was there until I put the breakpoint at the line?
Ben Jakuben
Treehouse TeacherThat's probably unrelated. With the breakpoint at that line, are you able to mouseover blogPosts and see what it contains? You might also want to add a breakpoint in your for loop where you call blogPosts.add(blogPost);. In fact, depending on what you've looked at so far, you might want to start looking at things at mBlogData = result; in your onPostExecute() method. You'll want to make sure that you are at least getting something in result! :)
Debugging is a pain - you need to start from the point where you know things last worked and then step through from there. So if you're getting data; great--you can move on to looking at the code in your handleBlogResponse method. But if not, then you'll need to figure out why you aren't getting any data first.
Neil Quinn
768 Pointsno see the application literally quits when its run from the emulator....so it will begin and stay at the sign in screen for a second, then quit.
here is my full app on github https://github.com/neilquinn91/MyApp
Ben Jakuben
Treehouse TeacherOkay, I will try to take a look and reply in here tomorrow. :)
Neil Quinn
768 Pointsthank you :)
Neil Quinn
768 PointsI added in the line of code to the newest version of the app and it didn't work, but I tracked back a version and it worked! :) Thanks!
Ben Jakuben
Treehouse TeacherAwesome - glad to hear it!