2014-09-06 2 views
10

Я пытаюсь преобразовать предыдущий учебник по управлению в Фрагмент, но я продолжаю работать с ошибкой NullPointerException на моем адаптере.Android Volley Null Pointer Exception

Учебное пособие основано на this, и я сократил конструктор адаптера, потому что он назывался Activity.

Существует одно возможное решение 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 и попытайтесь создать нечто подобное. Вот версия Google, но попробуйте также найти примеры: http://developer.android.com/training/improving-layouts/smooth-scrolling.html –

ответ

1

Глядя на ошибки, похоже, что вы звоните getActivity() внутри onCreateView(). Вы должны получать активность в onActivityCreated, а не там, где она не должна быть нулевой.

+0

Что вы предлагаете мне делать? Он должен быть фрагментом, а не активным. Не могли бы вы, например, написать пример? – user2793987

+0

Можете ли вы объяснить, почему вам нужно достичь активности, чтобы найти список? Является ли список не внутри R.layout.mainviewcontroller2_fragment? – bph

+0

Можете ли вы просмотреть обновленный код и ошибку logcat, пожалуйста? – user2793987

1

Изменить это от

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

в

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

Это происходит потому, что getActivity() обычно используется как для Context в фрагменте. Пока вы найдете идентификатор для своих UI элементов в Fragment, вам необходимо указать ссылку на ваш объект View's, который будет возвращен в onCreateView() методе.

Update:

Изменить ваш адаптер Как,

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

+0

Хорошо, я обновил свой пост, чтобы отразить ваши изменения. Однако теперь проблема заключается в конструкторе. См. Обновленный лог-код выше, пожалуйста. – user2793987

+0

добавьте эту линию inflater = LayoutInflater.from (контекст) к вашему конструктору адаптера – Piyush

26

Я думаю, вы пропустили простой код в файле манифеста. Ваш AppController пакет расширяет Application, поэтому тег приложения в манифесте ищет AppController, но не может найти.

Просто Написать этот простой код в ваш AndroidManifest.xml

android:name = your.package.AppController

+1

сэр, вы заходите вовремя. –

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 имеет значение null.

Надеется, что это помогает :)

+0

Спасибо! Никогда слишком поздно haha ​​ – CodeGuru

+0

слишком поздно ответ помог мне :-) –

+0

Если вы не можете, потому что у вас мультидексы? – delive

0

Пожалуйста, проверьте весь ваш Params тщательно, убедитесь, что не отправлять нулевое значение в 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; 
}