2014-09-06 16 views
10

Ich versuche, ein zuvor Activity-basierte Tutorial in ein Fragment zu konvertieren, aber ich fahre fort, in den NullPointerException-Fehler auf meinem Adapter zu laufen.Android Volley Null Pointer Ausnahme

Das Tutorial basiert auf this und ich habe den Konstruktor für den Adapter abgespeckt, weil es eine Aktivität aufgerufen hat.

Es gibt eine mögliche Lösung here aber niemand weiß, wie man mit der gleichen möglichen Frage fortfährt.

Ich möchte alles in ein funktionierendes Fragment umwandeln. Bitte lassen Sie mich wissen, wenn Sie weitere Informationen von mir benötigen.

Haupt konvertierte Klasse:

public class mainViewController2 extends Fragment { 
    private static final String TAG = mainViewController2.class.getSimpleName(); 
    private ListView listView; 
    private FeedListAdapter listAdapter; 
    private List<FeedItem> feedItems; 
    private String URL_FEED = "http://api.androidhive.info/feed/feed.json"; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) { 

     View v = inflater.inflate(R.layout.mainviewcontroller2_fragment, container, false); 

     listView = (ListView) v.findViewById(R.id.list); 

     feedItems = new ArrayList<FeedItem>(); 


     //where the error shows up? 
     listAdapter = new FeedListAdapter(feedItems); 
     listView.setAdapter(listAdapter); 



     // We first check for cached request 
     Cache cache = AppController.getInstance().getRequestQueue().getCache(); 
     Entry entry = cache.get(URL_FEED); 
     if (entry != null) { 
      // fetch the data from cache 
      try { 
       String data = new String(entry.data, "UTF-8"); 
       try { 
        parseJsonFeed(new JSONObject(data)); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } 

     } else { 
      // making fresh volley request and getting json 
      JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET, 
        URL_FEED, null, new Response.Listener<JSONObject>() { 

         @Override 
         public void onResponse(JSONObject response) { 
          VolleyLog.d(TAG, "Response: " + response.toString()); 
          if (response != null) { 
           parseJsonFeed(response); 
          } 
         } 
        }, new Response.ErrorListener() { 

         @Override 
         public void onErrorResponse(VolleyError error) { 
          VolleyLog.d(TAG, "Error: " + error.getMessage()); 
         } 
        }); 

      // Adding request to volley request queue 
      AppController.getInstance().addToRequestQueue(jsonReq); 
     } 

     return v; 
    } 

    /** 
    * Parsing json reponse and passing the data to feed view list adapter 
    * */ 
    private void parseJsonFeed(JSONObject response) { 
     try { 
      JSONArray feedArray = response.getJSONArray("feed"); 

      for (int i = 0; i < feedArray.length(); i++) { 
       JSONObject feedObj = (JSONObject) feedArray.get(i); 

       FeedItem item = new FeedItem(); 
       item.setId(feedObj.getInt("id")); 
       item.setName(feedObj.getString("name")); 

       // Image might be null sometimes 
       String image = feedObj.isNull("image") ? null : feedObj 
         .getString("image"); 
       item.setImge(image); 
       item.setStatus(feedObj.getString("status")); 
       item.setProfilePic(feedObj.getString("profilePic")); 
       item.setTimeStamp(feedObj.getString("timeStamp")); 

       // url might be null sometimes 
       String feedUrl = feedObj.isNull("url") ? null : feedObj 
         .getString("url"); 
       item.setUrl(feedUrl); 

       feedItems.add(item); 
      } 

      // notify data changes to list adapater 
      listAdapter.notifyDataSetChanged(); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

FeedListAdapter:

public class FeedListAdapter extends BaseAdapter { 
    private Activity activity; 
    private LayoutInflater inflater; 
    private List<FeedItem> feedItems; 

    Context context; 

    ImageLoader imageLoader; 

    public FeedListAdapter(Context ctx,List<FeedItem> feedItems) { 
     this.context= ctx; 
     this.feedItems = feedItems; 
     imageLoader = AppController.getInstance().getImageLoader(); 
     inflater = LayoutInflater.from(context); 
    } 

    @Override 
    public int getCount() { 
     return feedItems.size(); 
    } 

    @Override 
    public Object getItem(int location) { 
     return feedItems.get(location); 
    } 
     @Override 
     public long getItemId(int position) { 
      return position; 
     } 

     @SuppressLint("InflateParams") 
     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 

      if (inflater == null) 
       inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      if (convertView == null) 
       convertView = inflater.inflate(R.layout.feed_item, null); 

      if (imageLoader == null) 
       imageLoader = AppController.getInstance().getImageLoader(); 

      TextView name = (TextView) convertView.findViewById(R.id.name); 
      TextView timestamp = (TextView) convertView 
        .findViewById(R.id.timestamp); 
      TextView statusMsg = (TextView) convertView 
        .findViewById(R.id.txtStatusMsg); 
      TextView url = (TextView) convertView.findViewById(R.id.txtUrl); 
      NetworkImageView profilePic = (NetworkImageView) convertView 
        .findViewById(R.id.profilePic); 
      FeedImageView feedImageView = (FeedImageView) convertView 
        .findViewById(R.id.feedImage1); 

      FeedItem item = feedItems.get(position); 

      name.setText(item.getName()); 

      // Converting timestamp into x ago format 
      CharSequence timeAgo = DateUtils.getRelativeTimeSpanString(
        Long.parseLong(item.getTimeStamp()), 
        System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS); 
      timestamp.setText(timeAgo); 

      // Chcek for empty status message 
      if (!TextUtils.isEmpty(item.getStatus())) { 
       statusMsg.setText(item.getStatus()); 
       statusMsg.setVisibility(View.VISIBLE); 
      } else { 
       // status is empty, remove from view 
       statusMsg.setVisibility(View.GONE); 
      } 

      // Checking for null feed url 
      if (item.getUrl() != null) { 
       url.setText(Html.fromHtml("<a href=\"" + item.getUrl() + "\">" 
         + item.getUrl() + "</a> ")); 

       // Making url clickable 
       url.setMovementMethod(LinkMovementMethod.getInstance()); 
       url.setVisibility(View.VISIBLE); 
      } else { 
       // url is null, remove from the view 
       url.setVisibility(View.GONE); 
      } 

      // user profile pic 
      profilePic.setImageUrl(item.getProfilePic(), imageLoader); 

      // Feed image 
      if (item.getImge() != null) { 
       feedImageView.setImageUrl(item.getImge(), imageLoader); 
       feedImageView.setVisibility(View.VISIBLE); 
       feedImageView 
         .setResponseObserver(new FeedImageView.ResponseObserver() { 
          @Override 
          public void onError() { 
          } 

          @Override 
          public void onSuccess() { 
          } 
         }); 
      } else { 
       feedImageView.setVisibility(View.GONE); 
      } 

      return convertView; 
     } 

    } 

LogCat Fehler:

09-06 02:51:55.823: E/AndroidRuntime(8279): FATAL EXCEPTION: main 
09-06 02:51:55.823: E/AndroidRuntime(8279): Process: com.rynovation.kline, PID: 8279 
09-06 02:51:55.823: E/AndroidRuntime(8279): java.lang.NullPointerException 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at androidFeedClasses.FeedListAdapter.<init>(FeedListAdapter.java:35) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at com.rynovation.kline.mainViewController2.onCreateView(mainViewController2.java:51) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.Fragment.performCreateView(Fragment.java:1700) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.BackStackRecord.run(BackStackRecord.java:684) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1453) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.os.Handler.handleCallback(Handler.java:733) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.os.Handler.dispatchMessage(Handler.java:95) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.os.Looper.loop(Looper.java:146) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at android.app.ActivityThread.main(ActivityThread.java:5487) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at java.lang.reflect.Method.invokeNative(Native Method) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at java.lang.reflect.Method.invoke(Method.java:515) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 
09-06 02:51:55.823: E/AndroidRuntime(8279):  at dalvik.system.NativeStart.main(Native Method) 
+0

Ihre Adapter ist überall. Lesen Sie über das ViewHolder-Muster und versuchen Sie, etwas Ähnliches zu erstellen. Hier ist die Google-Version, aber versuchen Sie auch, nach Beispielen zu suchen: http://developer.android.com/training/improving-layouts/smooth-scrolling.html –

Antwort

1

am error Suche, scheint es, wie Sie getActivity() innerhalb onCreateView() sind aufgerufen wird. Sie sollten stattdessen die Aktivität in onActivityCreated erhalten, wo es nicht null sein sollte. dieser

+0

Was schlagen Sie vor, dass ich tue? Es soll ein Fragment sein, keine Aktivität. Kannst du bitte ein Beispiel schreiben, wenn möglich? – user2793987

+0

Können Sie erklären, warum Sie in die Aktivität gelangen müssen, um die Listenansicht zu finden? Befindet sich die ListView nicht in R.layout.mainviewcontroller2_fragment? – bph

+0

Können Sie den aktualisierten Code und Logcat Fehler bitte sehen? – user2793987

1

Wechsel von

listView = (ListView) getActivity().findViewById(R.id.list); 

zu

listView = (ListView)v.findViewById(R.id.list); 

Dies liegt daran, getActivity() im Allgemeinen für als Context in Fragmente verwendet wird. Während Sie ID für Ihre Elemente in Fragment finden, dann müssen Sie Referenz Ihres View's Objekts geben, das in onCreateView() Methode zurückgegeben wird.

Update:

ändern Sie Ihren Adapter Wie,

listAdapter = new FeedListAdapter(getActivity(),feedItems); 

Jetzt in seinem Constructor

ImageLoader imageLoader; 

public FeedListAdapter(Context ctx,List<FeedItem> feedItems) { 
    this.context= ctx; 
    this.feedItems = feedItems; 
    imageLoader = AppController.getInstance().getImageLoader() 
} 

Jetzt in Ihrer Adapter-Klasse Verwendung context Variable als Context.

+0

Danke, aber ich bekomme immer noch den gleichen Fehler. Ich denke, dass dies im FeedListAdapter verursacht werden kann? – user2793987

+0

Ok, ich habe auch meinen Beitrag aktualisiert, um deine Änderungen wiederzugeben. Das Problem scheint jetzt jedoch im Konstruktor zu liegen. Siehe aktuelles Logcat oben bitte. – user2793987

+0

fügen Sie diese Zeile inflater = LayoutInflater.from (context) zu Ihrem Adapterkonstruktor hinzu – Piyush

26

Ich denke, Sie haben einen einfachen Code in Ihrer Manifest-Datei verpasst. Ihr AppController Paket erweitert sich Application, also das Anwendungs-Tag in Ihrem Manifest sucht nach dem aber ist nicht in der Lage zu finden.

Schreiben Sie einfach diesen einfachen Code in Ihrem AndroidManifest.xml

android:name = your.package.AppController

+1

Sir, Sie sind Zeit sparen. –

11

etwas spät vielleicht, aber eine repräsentative Antwort auf user3902144 Antwort:

ähnliche Antwort auf diese Frage: Link

Sie Möglicherweise haben Sie dies aus Ihrem Manifest verpasst:

<application 
     android:name="<package-name>.app.AppController" // <-- this one 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme"> 

Deshalb wird onCreate nie aufgerufen und mInstance ist null.

this helps :)

+0

Danke! Nie zu spät haha ​​ – CodeGuru

+0

zu spät Antwort hat mir geholfen :-) –

+0

Wenn Sie nicht können, weil Multidex haben? – delive

0

Bitte überprüfen Sie alle params sorgfältig, stellen Sie sicher, dass keine Nullwert in params zu senden, wenn einige gespeicherten Werte verwenden dann die Bedingung verwenden, wie unten:

@Override 
protected Map<String, String> getParams() { 
Map<String, String> params = new HashMap<String, String>(); 
if(paramValue!= null) 
    params.put("paramKey", paramValue); 
    else 
    params.put("paramKey", "anyOtherDefaultValue"); 
return params; 
} 
Verwandte Themen