5

I have a product list but Java complains that the method exceeds the limit of 65535 bytes. How can I add more words and overcome the limit?

public class ProductList extends Activity {

   // List view
private ListView lv;

// Listview Adapter
ArrayAdapter<String> adapter;

// Search EditText
EditText inputSearch;

// ArrayList for Listview
ArrayList<HashMap<String, String>> productList;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_product_list);


    String as = System.getProperty("line.separator");

    String products[] = {


            // I want these words to keep in a database
            // Because here is 65kb limit but I need more...



            "Banana"    +as+    "Its color is yellow."  ,
            "Orange"    +as+    "Orange is a sour fruit."   ,
            "Onion" +as+    "Onion usually used on Pizza"   ,
            "Google"    +as+ "Google is a giant search engine." ,
            "Love"  +as+    "Love is related to heart." ,
            "Lily"  +as+    "It  is one kind of white flower."  ,
            "Banana"    +as+    "Its color is yellow."  ,
            "Orange"    +as+    "Orange is a sour fruit."   ,
            "Onion" +as+    "Onion usually used on Pizza"   ,
            "Google"    +as+ "Google is a giant search engine." ,
            "Love"  +as+    "Love is related to heart." ,
            "Lily"  +as+    "It  is one kind of white flower."  ,           
            "Banana"    +as+    "Its color is yellow."  ,
            "Orange"    +as+    "Orange is a sour fruit."   ,
            "Onion" +as+    "Onion usually used on Pizza"   ,
            "Google"    +as+ "Google is a giant search engine." ,







    };



    lv = (ListView) findViewById(R.id.list_view);
    inputSearch = (EditText) findViewById(R.id.inputSearch);

    // Adding items to listview
    adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.p_list,   products);
    lv.setAdapter(adapter);

    /**
     * Enabling Search Filter
     * */
    inputSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            // When user changed the Text
            ProductList.this.adapter.getFilter().filter(cs);
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub
        }
    });


}

}

For easier understanding:

enter image description here

Thanks in advance

Eonasdan
  • 7,563
  • 8
  • 55
  • 82
Jani
  • 133
  • 2
  • 7

3 Answers3

8

This isn't a limitation to do with Sqlite as far as I can tell - the Eclipse error is showing that it's a problem with the method.

I would strongly suggest that if you have a lot of data, you should keep that in a separate resource. Then just load the resource at execution time. There's no need to have it baked into your code. You can always include some string to replace with the platform line separator if you need to.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    "Strongly" should also be bolded and underlined. This is just the wrong approach :) – dmon Dec 12 '12 at 18:46
2

You're allocating that array on the stack, and the stack usually has a 64kb limit in how much it can hold.

Your solution is to use the heap. If you changed your code to be

// allocate an array on the heap
ArrayList<String> products = new ArrayList<String>();
products.add("Banana" +as+ "Its color is yellow.");
products.add("Orange" +as+ "Orange is a sour fruit.");
products.add("Onion" +as+ "Onion usually used on Pizza");
// etc

Then I bet that would work.

Your best option, however, is to do what Jon Skeet said and store all that data in a resource and load it when you need it. Since it looks like you're using Android, I would suggest using String Arrays, which is how you're supposed to handle this type of data.

UPDATE:

Interesting. So it turns out that this is a Java limitation. See this answer. My understanding is that the jump offsets in class files are 16-bit, which means that methods can be, at most, 65535 bytes in size.

So the hack solution is to split this into smaller methods:

// allocate an array on the heap
ArrayList<String> products = new ArrayList<String>();
addFirstThousand(products);
addSecondThousand(products);
// etc.

private void addFirstThousand(ArrayList<String> products) {
    products.add("Banana" +as+ "Its color is yellow.");
    products.add("Orange" +as+ "Orange is a sour fruit.");
    products.add("Onion" +as+ "Onion usually used on Pizza");
    // etc
}

But that is a terrible idea. It really would be better to put those strings in some sort of data file and then load it at runtime. If for some reason you're really opposed to doing the right thing and using the String Array that Google has provided you, then you could also just put those strings in a text file in assets, and read it in through the normal Java BufferedReader.

Community
  • 1
  • 1
Steve Blackwell
  • 5,904
  • 32
  • 49
  • As I am new to android, I like ur style. But unfortunately it has the same problem. Have a look https://dl.dropbox.com/u/15065300/problem-2.png – Jani Dec 12 '12 at 19:24
  • Boss, You might be very busy but therefore requesting you to add a small text file in my app here http://www.mediafire.com/?83bol5mhgromgg0 Big thanks in advance – Jani Dec 13 '12 at 19:04
0

The solution is to allocate objects dynamically into the heap, which is virtually infinite.

GitaarLAB
  • 14,536
  • 11
  • 60
  • 80
HAL9000
  • 3,562
  • 3
  • 25
  • 47