使用universalimageloader时出错

时间:2014-12-23 09:21:46

标签: android android-view android-library

我在我的应用程序中发现了一个错误,但我无法修复它。我使用SwipeRefreshLayout,他帮助发现了一个bug。当我在列表的一个片段上并尝试更新SwipeRefreshLayout时,如果这次我转到应用程序的另一个片段就会起飞。

ERROR:

java.lang.NullPointerException
            at com.nostra13.universalimageloader.core.ImageLoaderConfiguration$Builder.<init>(ImageLoaderConfiguration.java:196)
            at com.nostra13.universalimageloader.core.ImageLoaderConfiguration.createDefault(ImageLoaderConfiguration.java:127)
            at com.managment.pavel.managmentgradle.fragments.adapters.EmployeeListAdapter.<init>(EmployeeListAdapter.java:52)
            at com.managment.pavel.managmentgradle.fragments.EmployeessList$1.onPostExecute(EmployeessList.java:109)
            at com.managment.pavel.managmentgradle.fragments.EmployeessList$1.onPostExecute(EmployeessList.java:69)
            at android.os.AsyncTask.finish(AsyncTask.java:417)
            at android.os.AsyncTask.access$300(AsyncTask.java:127)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:130)
            at android.app.ActivityThread.main(ActivityThread.java:3683)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:507)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
            at dalvik.system.NativeStart.main(Native Method)

我只使用在片段的构造函数中初始化的库ImageLoader

在适配器的构造函数中初始化:

public class EmployeeListAdapter extends SectionedBaseAdapter {
    private ArrayList<String> sections;
    private ArrayList<List<EmployeesListBean>> employees;
    private ImageLoader imageLoader = ImageLoader.getInstance();
    private DisplayImageOptions options;
    private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
    private Context context;

    public EmployeeListAdapter(ArrayList<EmployeesListBean> employeesListBeans, Context context) {
        this.context = context;

        Map<String, List<EmployeesListBean>> map = new HashMap<>();
        for (EmployeesListBean employeesListBean : employeesListBeans) {
            if (!map.containsKey(employeesListBean.getDepart_name()))
                map.put(employeesListBean.getDepart_name(), new ArrayList<EmployeesListBean>());
            map.get(employeesListBean.getDepart_name()).add(employeesListBean);
        }
        sections = new ArrayList<>(map.keySet());
        employees = new ArrayList<>(map.values());
        options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.ic_stub)
                .showImageForEmptyUri(R.drawable.ic_empty)
                .showImageOnFail(R.drawable.ic_error)
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .build();
        imageLoader.init(ImageLoaderConfiguration.createDefault(context));
    }

错误指向字符串:

imageLoader.init(ImageLoaderConfiguration.createDefault(context));

请告诉我我做错了什么?初始化可能需要在其他地方进行吗?

EDITE MY FRAGMENT(FULL):

public class EmployeessList extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
    private String link;
    private PinnedHeaderListView listView;
    private SwipeRefreshLayout swipeLayout;
    private ProgressDialog progressDialog;
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.employeelist, null);
        swipeLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_employe_list);
        swipeLayout.setColorSchemeColors(Color.RED, Color.GREEN, Color.BLUE, Color.CYAN);
        swipeLayout.setOnRefreshListener(this);

        listView = (PinnedHeaderListView) v.findViewById(R.id.pinnedListView);
        link=getArguments().getString(MyActivity.ARGUMENT_LINK);
        if (InternetResiver.isOnline(getActivity())) {
            progressDialog = MyProgress.getProgressDialog(getActivity());
            progressDialog.show();
           setData();
        } else {
            AlertDialog alert = InternetResiver.getAlertDialog(getActivity());
            alert.show();
        }
        return v;
    }

    @Override
    public void onRefresh() {
        if (InternetResiver.isOnline(getActivity())) {
          setData();
        } else {
            AlertDialog alert = InternetResiver.getAlertDialog(getActivity());
            alert.show();
        }
    }

    public void setData(){


        new MyAsincTask(getActivity()){
            int city = 0;
            int holiday = 0;
            @Override
            protected void onPreExecute() {
            }

            @Override
            protected void onPostExecute(Document document) {
                super.onPostExecute(document);
                ArrayList<EmployeesListBean> employeesListBeans = new ArrayList<>();
                Elements elementsUid = document.select("uid");
                Elements elementsStaffName = document.select("staff_name");
                Elements elementsDepartName = document.select("depart_name");
                Elements elementsLocation = document.select("location");
                Elements elementsInTime = document.select("in_time");
                Elements elementsOutTime = document.select("out_time");
                Elements elementsLateness = document.select("lateness");
                Elements elementsPhoto = document.select("photo");

                for (int i = 0; i < elementsUid.size(); i++) {
                    EmployeesListBean employeesListBean = new EmployeesListBean();
                    employeesListBean.setUid(elementsUid.get(i).ownText());
                    employeesListBean.setStaff_name(elementsStaffName.get(i).ownText());
                    employeesListBean.setDepart_name(elementsDepartName.get(i).ownText());
                    employeesListBean.setLocation(elementsLocation.get(i).ownText());
                    employeesListBean.setIn_time(elementsInTime.get(i).ownText());
                    employeesListBean.setOut_time(elementsOutTime.get(i).ownText());
                    employeesListBean.setLateness(elementsLateness.get(i).ownText());
                    employeesListBean.setPhoto(elementsPhoto.get(i).ownText());

                    employeesListBeans.add(employeesListBean);

                    if (employeesListBeans.get(i).getOut_time().equals("на смене") && elementsLocation.get(i).ownText().equals("city")) {
                        city += 1;
                    }
                    if(employeesListBeans.get(i).getOut_time().equals("на смене") && elementsLocation.get(i).ownText().equals("holiday")){
                        holiday += 1;
                    }
                }
                EmployeeListAdapter sectionedAdapter = new EmployeeListAdapter(employeesListBeans, getActivity());
                listView.setAdapter(sectionedAdapter);
                progressDialog.cancel();
                swipeLayout.setRefreshing(false);
                getActivity().setTitle("Сотрудники(city:" + city + ",holiday:" + holiday + ")");
            }
        }.execute(link);
    }
}

我的适配器(全部):

public class EmployeeListAdapter extends SectionedBaseAdapter {
    private ArrayList<String> sections;
    private ArrayList<List<EmployeesListBean>> employees;
    private ImageLoader imageLoader = ImageLoader.getInstance();
    private DisplayImageOptions options;
    private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
    private Context context;

    public EmployeeListAdapter(ArrayList<EmployeesListBean> employeesListBeans, Context context) {
        this.context = context;

        Map<String, List<EmployeesListBean>> map = new HashMap<>();
        for (EmployeesListBean employeesListBean : employeesListBeans) {
            if (!map.containsKey(employeesListBean.getDepart_name()))
                map.put(employeesListBean.getDepart_name(), new ArrayList<EmployeesListBean>());
            map.get(employeesListBean.getDepart_name()).add(employeesListBean);
        }
        sections = new ArrayList<>(map.keySet());
        employees = new ArrayList<>(map.values());
        options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.ic_stub)
                .showImageForEmptyUri(R.drawable.ic_empty)
                .showImageOnFail(R.drawable.ic_error)
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .build();
        imageLoader.init(ImageLoaderConfiguration.createDefault(context));
    }

    @Override
    public Object getItem(int section, int position) {
        return employees.get(section).get(position);
    }

    @Override
    public long getItemId(int section, int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int getSectionCount() {
        return sections.size();
    }

    @Override
    public int getCountForSection(int section) {
        return employees.get(section).size();
    }

    @Override
    public View getItemView(int section, int position, View convertView, ViewGroup parent) {
        LinearLayout layout;
        if (convertView == null) {
            LayoutInflater inflator = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            layout = (LinearLayout) inflator.inflate(R.layout.itememploee, null);
        } else {
            layout = (LinearLayout) convertView;
        }
        ((TextView) layout.findViewById(R.id.staff_name_text)).setText(employees.get(section).get(position).getStaff_name());
        ((TextView) layout.findViewById(R.id.depart_name_text)).setText("Должность: " + employees.get(section).get(position).getDepart_name());
        ((TextView) layout.findViewById(R.id.location_text)).setText("Отель: " + employees.get(section).get(position).getLocation());
        ((TextView) layout.findViewById(R.id.in_time_text)).setText("Пришел: " + employees.get(section).get(position).getIn_time());
        ((TextView) layout.findViewById(R.id.out_time_text)).setText("Ушел: " + employees.get(section).get(position).getOut_time());
        ((TextView) layout.findViewById(R.id.lateness_text)).setText("Опоздание: " + employees.get(section).get(position).getLateness());
        imageLoader.displayImage(employees.get(section).get(position).getPhoto(), (CircleImageView) layout.findViewById(R.id.employeePhoto), options, animateFirstListener);
        if (employees.get(section).get(position).getOut_time().equals("на смене")) {
            layout.setBackgroundColor(context.getResources().getColor(R.color.employe_positive));
        }else{
            layout.setBackgroundColor(context.getResources().getColor(R.color.employe_negative));
        }
        return layout;
    }

    @Override
    public View getSectionHeaderView(int section, View convertView, ViewGroup parent) {
        LinearLayout layout;
        if (convertView == null) {
            LayoutInflater inflator = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            layout = (LinearLayout) inflator.inflate(R.layout.header_item_employee, null);
        } else {
            layout = (LinearLayout) convertView;
        }
        ((TextView) layout.findViewById(R.id.textItem)).setText(sections.get(section));
        return layout;
    }


}

3 个答案:

答案 0 :(得分:1)

总是一个好主意看一下开源库的源代码:)。

代码在这里(我假设您使用的是最新版本): https://github.com/nostra13/Android-Universal-Image-Loader/blob/master/library/src/com/nostra13/universalimageloader/core/ImageLoaderConfiguration.java

有问题的一行:

195         public Builder(Context context) { 
196             this.context = context.getApplicationContext(); 
197         } 

这意味着上下文为空。看看你的适配器,看看是否确实如此。

此外,非常重要的是要注意,您只需要在每次使用时初始化图像加载器 。在您的主要启动器活动中或在您的应用程序类中更好(只要您在清单中覆盖它)。如果需要覆盖默认选项,则每个方法都有一个覆盖,允许您指定加载选项。

更新:

要创建应用程序类,请遵循以下教程:http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android

然后在应用程序类的onCreate()方法中,通过调用init()方法初始化ImageLoader。不要在过渡类(适配器)中执行此操作。 Application类可以访问ApplicationContext,这是您需要传递给init()方法的。

<强> UPDATE2:

根据https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Quick-Setup,如果您愿意,可以在主要活动中对其进行初始化。

public class MyActivity extends Activity {
@Override
public void onCreate() {
    super.onCreate();

    // Create global configuration and initialize ImageLoader with this config
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
        ...
        .build();
    ImageLoader.getInstance().init(config);
    ...
    }
}

要在应用中获取任何地方的图像加载器实例,只需调用ImageLoader.getInstance()

即可使用单例实例

答案 1 :(得分:0)

private ImageLoader imageLoader = ImageLoader.getInstance();

这样做

private ImageLoader imageLoader ;

constructor(){

   DisplayImageOptions defaultDisplayImageOptions = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.drawable.ic_stub)
            .showImageForEmptyUri(R.drawable.ic_empty)
            .showImageOnFail(R.drawable.ic_error).cacheInMemory(true)
            .cacheOnDisk(true).build();



    ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(
            context).threadPriority(Thread.NORM_PRIORITY - 2)
            .denyCacheImageMultipleSizesInMemory()
            .defaultDisplayImageOptions(defaultDisplayImageOptions);

    ImageLoaderConfiguration config = builder.build();

    // Initialize ImageLoader with configuration.
    ImageLoader.getInstance().init(config);


}

答案 2 :(得分:0)

在构造函数中以这种方式尝试:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
//do whatever you want
.writeDebugLogs()
.build();

imageLoader.init(config);