Android在线程中设置自定义适配器字符串数组大小



我正在尝试从数据库设置数组长度,我得到这个错误:

EE/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.cekmekoytipmerkezi.diyetisyen.diyetisyen, PID: 11676
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cekmekoytipmerkezi.diyetisyen.diyetisyen/com.cekmekoytipmerkezi.diyetisyen.diyetisyen.DiyetisyenActivity}: java.lang.NullPointerException: Attempt to get length of null array
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3253)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349)
                  at android.app.ActivityThread.access$1100(ActivityThread.java:221)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:158)
                  at android.app.ActivityThread.main(ActivityThread.java:7224)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
               Caused by: java.lang.NullPointerException: Attempt to get length of null array
                  at com.cekmekoytipmerkezi.diyetisyen.diyetisyen.AkisArrayAdapter.getCount(AkisArrayAdapter.java:47)
                  at android.widget.ListView.setAdapter(ListView.java:508)
                  at com.cekmekoytipmerkezi.diyetisyen.diyetisyen.AkisFragment.onCreateView(AkisFragment.java:136)
                  at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                  at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
                  at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
                  at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
                  at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
                  at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:601)
                  at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1265)
                  at android.app.Activity.performStart(Activity.java:6915)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3216)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349) 
                  at android.app.ActivityThread.access$1100(ActivityThread.java:221) 
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794) 
                  at android.os.Handler.dispatchMessage(Handler.java:102) 
                  at android.os.Looper.loop(Looper.java:158) 
                  at android.app.ActivityThread.main(ActivityThread.java:7224) 
                  at java.lang.reflect.Method.invoke(Native Method) 
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
                  at java.lang.Thread.run(Thread.java:818)

基本上我有一个列表视图,我需要从我的数据库填充。我已经创建了一个自定义适配器。在我的片段中,当我在初始声明中设置String[] ogunler = new String[10];并且在线程中不做任何事情时,我接收到数据,但在实际数据之后我有一堆空列表项。

我的片段代码:

public class AkisFragment extends Fragment
{
    String[] ogunler;
    int hastaID;
    String dayOfTheWeek;
    int programID;
    AkisArrayAdapter adapter;
    public AkisFragment()
    {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.fragment_akis, container, false);
        Calendar calendar = Calendar.getInstance();
        final int day = calendar.get(Calendar.DAY_OF_WEEK);
        String SQL = "SELECT email, sifre, ID FROM Hasta WHERE Hasta.email = '";
        Bundle bundle = this.getArguments();
        if (bundle != null)
        {
            hastaID = bundle.getInt("hastaID");
        }
        ...
        new Thread(new Runnable()
        {
            public void run()
            {
                try
                {
                    Class.forName("net.sourceforge.jtds.jdbc.Driver");
                    Connection conn = DriverManager.getConnection(getResources().getString(R.string.db_connection));
                    dayOfTheWeek = "Pazartesi";
                    String SQL = "SELECT ID FROM Program Where hastaID = " + Integer.toString(hastaID) + "AND gun = '" + dayOfTheWeek + "'";
                    Log.w(dayOfTheWeek, "123");
                    Statement stmt = conn.createStatement();
                    ResultSet rs = stmt.executeQuery(SQL);
                    int counter = 0;
                    while (rs.next())
                    {
                        programID = rs.getInt(1);
                    }
                    String SQLcounter = "SELECT ID FROM Program Where hastaID = " + Integer.toString(hastaID) + "AND gun = '" + dayOfTheWeek + "'";
                    Statement stmtCounter = conn.createStatement();
                    ResultSet rsCounter = stmtCounter.executeQuery(SQLcounter);
                    int arrSize = 0;
                    while(rsCounter.next())
                    {
                        arrSize++;
                    }
                    ogunler = new String[arrSize];
                    SQL = "SELECT ogunTipi, ogunIcerik FROM Ogun WHERE programID = " + Integer.toString(programID);
                    Statement stmt2 = conn.createStatement();
                    ResultSet rs2 = stmt2.executeQuery(SQL);
                    int counter2 = 0;
                    while (rs2.next())
                    {
                        ogunler[counter2] = rs2.getString(2) + " " + rs2.getString(1);
                        //Log.w(ogunler[counter2], "123");
                        counter2++;
                    }
                    getActivity().runOnUiThread(new Runnable()
                    {
                        public void run()
                        {
                            adapter.notifyDataSetChanged();
                        }
                    });
                    conn.close();
                } catch (ClassNotFoundException e)
                {
                    e.printStackTrace();
                } catch (SQLException e)
                {
                    e.printStackTrace();
                }
            }
        }).start();

        ListView list = (ListView) view.findViewById(R.id.lvAkis);
        adapter = new AkisArrayAdapter(getActivity(), ogunler);
        list.setAdapter(adapter);
        return view;
    }
}

定制适配器:

public class AkisArrayAdapter extends BaseAdapter
{
    String items[];
    int programID;
    LayoutInflater mInflater;
    public AkisArrayAdapter(Context context, String[] _items)
    {
        mInflater = LayoutInflater.from(context);
        this.items = _items;
    }

    @Override
    public int getCount()
    {
        return items.length;
    }
    @Override
    public Object getItem(int position)
    {
        return position;
    }
    @Override
    public long getItemId(int position)
    {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder holder;
        if(convertView == null)
        {
            convertView = mInflater.inflate(R.layout.aks_list_item, parent, false);
            holder = new ViewHolder();
            holder.tv = (TextView) convertView.findViewById(R.id.tvOgun);
            holder.iv = (ImageView) convertView.findViewById(R.id.ivOgun);
            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tv.setText(items[position]);
        if (holder.tv.getText().toString().endsWith("Ana Öğün"))
        {
            holder.iv.setImageResource(R.mipmap.ana);
        }
        else if (holder.tv.getText().toString().endsWith("Ara Öğün"))
        {
            holder.iv.setImageResource(R.mipmap.ara);
        }
        else if (holder.tv.getText().toString().endsWith("Ek Öğün"))
        {
            holder.iv.setImageResource(R.mipmap.ek);
        }
        return convertView;
    }
    static class ViewHolder
    {
        ImageView iv;
        TextView tv;
    }
}

我做错了什么?

以异步方式获取数据。这意味着Android试图为你创建一个视图,但还没有数据。所以如果你一开始就提供一个空数组,这是可行的。然后在以后的体育场中,您可以设置适配器的结果并调用适配器上的notifyDataSetChanged()。

所以首先要解决NullPointerException,适配器中的项需要一个初始值。

public class AkisArrayAdapter extends BaseAdapter {
    String[] items = {};
    ...
    ...
}    

那么我认为您应该将新项设置为适配器。所以给适配器添加setter

public void setItems(String[] newItems) {
    this.items = newItems;
}
我希望我理解了这个问题,如果没有,请详细说明,我尽量帮助。(也许会得到一些分数;))

最新更新