问题
I am developing custom list field using Table Row Manager in blackberry.it displays list of items coming from web service.When i click on item it goes to other screen.But i am getting too many threads exception.after some time i am getting too many threads exception when i click on item.Then i check when the thread is creating by using debug.Then i found of displaying each item it creating separate thread.How can i solve this problem please help here is my custom list field class
class LabelListField extends ListField implements ListFieldCallback
{
private Vector mValues;
private Vector mRows;
DynamicImages images;
int[] intColor=new int[500];
int i=0;
int j=0,position;
static int value1=0;
String key;
String[] col;
public LabelListField(Vector values,int p,String key) {
super(0);
setRowHeight(70);
setCallback(this);
position=p;
mValues = values;
this.key=key;
fillListWithValues(values);
images=new DynamicImages();
scheduleInvalidate();
}
private void scheduleInvalidate() {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
invalidate();
}
}, 0, 100);
}
private void fillListWithValues(Vector values) {
mRows = new Vector();
for (;i< values.size();i++) {
TableRowManager row = new TableRowManager();
String value = (String) values.elementAt(i);
ListLabel valueLabel = new ListLabel(this,i,value);
if(Display.getWidth()==480)
{
valueLabel.setFont(Utility.getBigFont(16));
}
else
{
valueLabel.setFont(Utility.getBigFont(12));
}
row.add(valueLabel);
mRows.addElement(row);
}
setSize(mRows.size());
}
private class TableRowManager extends Manager {
public TableRowManager() {
super(0);
}
public void drawRow(Graphics g, int x, int y,
int width, int height) {
layout(width, height);
setPosition(x, y);
g.pushRegion(getExtent());
paintChild(g, getField(0));
Bitmap line=Bitmap.getBitmapResource(images.lightline);
g.drawBitmap(0,0,line.getWidth(),line.getHeight(),line,0,0);
g.popContext();
}
protected void sublayout(int width, int height) {
int fontHeight = Font.getDefault().getHeight();
int preferredWidth = getPreferredWidth();
Field field = getField(0);
layoutChild(field, preferredWidth,fontHeight + 1);
if(((ListLabel)field).getText().length()>110)
{
setPositionChild(field, 5,10);
}
else if(((ListLabel)field).getText().length()>55)
{
setPositionChild(field,5,20);
}
else if(((ListLabel)field).getText().length()<55)
{
setPositionChild(field,5,30);
}
//field = getField(1);
//layoutChild(field,18,24);
//setPositionChild(field,250,30);
setExtent(getPreferredWidth(), getPreferredHeight());
}
public int getPreferredWidth() {
return Display.getWidth();
}
public int getPreferredHeight() {
return getRowHeight();
}
}
public void drawListRow(ListField listField, Graphics g,
int index, int y, int width) {
String val=HomeScreenIcons.colorstable.get(key).toString();
col=StringToken.split(val,"||");
if (g.isDrawingStyleSet(Graphics.DRAWSTYLE_FOCUS))
{
LabelListField list = (LabelListField) listField;
g.setColor(0xC0C0C0);
g.fillRect(0,y+0,480,list.getRowHeight());
if(col[index].equals("1"))
{
g.setColor(0x004D7B);
}
else
{
g.setColor(Color.GRAY);
}
TableRowManager rowManager = (TableRowManager) list.mRows
.elementAt(index);
rowManager.drawRow(g,0,y,width,list.getRowHeight());
}
else
{
if(col[index].equals("1"))
{
g.setColor(0x004D7B);
}
else
{
g.setColor(Color.GRAY);
}
LabelListField list = (LabelListField) listField;
TableRowManager rowManager = (TableRowManager) list.mRows
.elementAt(index);
rowManager.drawRow(g,0,y,width,list.getRowHeight());
}
}
public Object get(ListField list, int index) {
return mValues.elementAt(index);
}
public int indexOfList(ListField list, String prefix, int start) {
for (int x = start; x < mValues.size(); ++x) {
String value = (String) mValues.elementAt(x);
if (value.startsWith(prefix)) {
return x;
}
}
return -1;
}
public int getPreferredWidth(ListField list) {
return Display.getWidth();
}
class ListLabel extends LabelField {
int mIndex = -1;
String text;
int[] color=new int[500];
public ListLabel(LabelListField list, int index, String text) {
super(text);
this.text=text;
mIndex = index;
System.out.println("position is"+position);
}
public int getPreferredWidth() {
return Display.getWidth()-80;
}
protected void layout(int maxWidth,int maxHeight) {
super.layout(getPreferredWidth(),maxHeight);
setExtent(getPreferredWidth(), getHeight());
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(0);
return true;
}
protected void fieldChangeNotify(int context){
if(context == 0){
try {
this.getChangeListener().fieldChanged(this, context);
} catch (Exception e){}
}
}
}
protected boolean trackwheelClick(int status, int time)
{
return true;
}
}
回答1:
koti, to add to your own answer - one of my BB apps also needs to fire threads for each row of the list.
BlackBerry can have only a few threads. I recommend creating a task worker thread, and queuing up tasks on it. That way you can have many background tasks running, but they are only on one thread.
Another option in your case would be to have only 1 Timer thread running, with a list of the rows. That 1 thread can then invalidate each row at a specific time. This is better than having a new Timer Thread for each row.
回答2:
useless Calling of scheduleInvalidate
method.By removing scheduleInvalidate()
it works fine
来源:https://stackoverflow.com/questions/7876499/too-many-threads-exception-while-using-custom-list-field-in-blackberry