2014-09-06 33 views
10

我試圖將先前基於Activity的教程轉換爲Fragment,但我繼續遇到我的Adapter上的NullPointerException錯誤。Android排球空指針異常

本教程是基於this,我已經瘦了適配器的構造函數,因爲它曾經是調用一個活動。

有一種可能的解決方案here但沒有人知道如何處理相同的可能問題。

我想將所有內容都轉換爲工作片段。如果您需要更多信息,請告訴我。

主要轉換類:

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的錯誤:

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

你適配器遍佈各處。閱讀關於ViewHolder模式並嘗試創建類似的東西。這裏是谷歌版本,但也嘗試搜索示例以及:http://developer.android.com/training/improving-layouts/smooth-scrolling.html – 2014-09-12 01:17:22

回答

1

望着錯誤,好像你打電話getActivity()onCreateView()。您應該在onActivityCreated中獲得活動,而不應該爲null。

+0

你建議我做什麼?它意味着一個片段,而不是一個活動。如果可能,你可以寫一個例子嗎? – user2793987 2014-09-06 06:12:44

+0

你能解釋爲什麼你需要進入活動來查找列表視圖?列表視圖不在R.layout.mainviewcontroller2_fragment裏面嗎? – bph 2014-09-06 06:17:12

+0

你能看看更新後的代碼和logcat錯誤嗎? – user2793987 2014-09-06 18:29:56

1

更改此從

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

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

這是因爲getActivity()通常用於在片段的Context。雖然你在片段中找到你的UI元素的ID,那麼你必須給出你的View's對象的參考,它將在onCreateView()方法中返回。

更新:

更改適配器一樣,

listAdapter = new FeedListAdapter(getActivity(),feedItems); 
在其構造

ImageLoader imageLoader; 

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

現在,在您的適配器類使用context變量作爲Context

現在。

+0

謝謝,但我仍然得到相同的錯誤。我認爲這可能是FeedListAdapter造成的? – user2793987 2014-09-06 06:34:20

+0

好的,我更新了我的帖子以反映您的更改。但是,現在的問題似乎在構造函數中。請參閱上面更新的logcat。 – user2793987 2014-09-06 06:48:17

+0

將此行inflater = LayoutInflater.from(上下文)添加到您的適配器構造函數 – Piyush 2014-09-06 06:49:31

26

我想你錯過了清單文件中的一個簡單代碼。您的AppController程序包擴展Application,因此清單中的應用程序標記正在搜索AppController但無法找到。

只寫這個簡單的代碼在你的AndroidManifest.xml

android:name = your.package.AppController

+1

先生,你是節省時間。 – 2015-12-23 21:52:45

11

有點晚了可能,但有代表性的回答user3902144的回答是:

類似的回答了這個問題:Link

你可能已經錯過了你的清單:

<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"> 

這就是爲什麼onCreate從未調用過且mInstance爲空。

希望這有助於:)

+0

謝謝!永遠不會太遲哈哈 – CodeGuru 2015-05-10 01:12:04

+0

太遲迴答幫助我:-) – 2015-06-23 03:20:10

+0

如果你不能因爲有multidex? – delive 2015-12-07 15:03:41

0

請仔細檢查所有的參數,可以確保不params中發送任何空值,如果使用一些存儲的值,然後使用如下的條件:

@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; 
}