Table get selected row index - android

I am having some problem when trying to get the value of the first column when the checkbox of certain row is checked using Android. Here is my codes:
private ArrayList<String> exerciseIDList = new ArrayList<String>();
private void BuildTable() {
try {
String sql = "SELECT * FROM exercise";
Cursor mCur = mDb.rawQuery(sql, null);
if (mCur.getCount() != 0) {
if (mCur.moveToFirst()) {
do {
int cols = mCur.getColumnCount();
TableRow row = new TableRow(this);
row.setLayoutParams(new LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
for (int j = 0; j < cols + 1; j++) {
if (j == cols) {
CheckBox cb = new CheckBox(this);
cb.setLayoutParams(new TableRow.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
cb.setGravity(Gravity.LEFT);
row.addView(cb);
final View rowIndex = table_layout.getChildAt(j);
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int rowID = table_layout.indexOfChild(rowIndex);
exerciseIDList.add(Integer.toString(rowID));
}
});
break;
}
TextView tv = new TextView(this);
tv.setLayoutParams(new TableRow.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tv.setGravity(Gravity.LEFT);
tv.setTextSize(10);
tv.setText(mCur.getString(j));
row.addView(tv);
}
table_layout.addView(row);
} while (mCur.moveToNext());
}
}
} catch (SQLException mSQLException) {
throw mSQLException;
}
}
Basically I have 3 columns in my database, ID, exerciseType and amount. When I do a for loop, I +1 the cols to add checkbox to the end of each row. And when the checkbox is checked, I supposed to get the value of the first column which is ID and store into the list.
However, from the codes I provided above, it does not get the value of the first column of checked row. It is just simply looping start from 0.
Any guides?

The issue you are having is that you are referring to a non-final variable inside an anonymous class (View.OnClickListener()). See this post for more information. I would suggest the following:
final int k = mCur.getInt(mCur.getColumnIndex("id")); //I'm not sure what you named your ID column, but put that here
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
exerciseIDList.add(Integer.toString(k));
}
});
Basically, just create a new final variable k and assign it to your return from the Cursor.getInt(). That should get you through this error.

Related

Android table layout

In my app i'am setting each table row in code.
Row setting code
final TableRow row = new TableRow(context);
row.setBackgroundResource(R.drawable.layer_nw);
row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 150));
row.setMinimumHeight(100);
//tr.addView(view);
String[] colText = {"" + outlet_name, "" + outlet_qty, "" + outlet_price, "" + outlet_tot};
for (String text : colText) {
TextView tv = new TextView(this);
//EditText ev=new EditText(this);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,150));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(14);
// tv.setTextColor(Integer.parseInt("#D3D3D3"));
tv.setText(text);
row.addView(tv);
}
tableLayout.addView(row);
in this row i want the second cell,that is 'outlet_qty' as edit text and all other as textview.each of the 'colText' array variables gets its value from Sqlite..
is there any way to achievethis?pls help
This all is to manage TextView and EditText for a specific column number. you can manage data input from sqlite as how you are doing as same.
final TableRow row = new TableRow(context);
row.setBackgroundResource(R.drawable.layer_nw);
row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 150));
row.setMinimumHeight(100);
//tr.addView(view);
String[] colText = {"" + outlet_name, "" + outlet_qty, "" + outlet_price, "" + outlet_tot};
for (int i = 0; i < colText.length; i++) {
EditText ev = new EditText(this);
TextView tv = new TextView(this);
if (i == 1) {//For outlet_qty
ev.setId(i);
ev.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, 150));
ev.setGravity(Gravity.CENTER);
ev.setTextSize(14);
// ev.setTextColor(Integer.parseInt("#D3D3D3"));
ev.setText(colText[i]);
ev.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 0) {
((TextView) row.findViewById(Integer.valueOf(3))).setText(s.toString().trim());
} else {
((TextView) row.findViewById(Integer.valueOf(3))).setText("");
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
row.addView(ev);
} else {
tv.setId(i);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, 150));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(14);
// tv.setTextColor(Integer.parseInt("#D3D3D3"));
tv.setText(colText[i]);
row.addView(tv);
}
}
tableLayout.addView(row);
try this. In the for Loop where you iterate over the columns we check if the colum is outlet_qty. if we match the outlet_qty column we add a Edit text. And for all other we add the text views.
final TableRow row = new TableRow(context);
row.setBackgroundResource(R.drawable.layer_nw);
row.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, 150));
row.setMinimumHeight(100);
//tr.addView(view);
String[] colText = {"" + outlet_name, "" + outlet_qty, "" + outlet_price, "" + outlet_tot};
// iterate over colunms
for (String text : colText) {
// add edit text for outlet_qty column
if(text.equals(outlet_qty))
{
EditText editText = new EditText(this);
// do stuff with the edit text like prefilling data etc
row.addView(tv);
}
// for all others we add text views
else
{
TextView tv = new TextView(this);
//EditText ev=new EditText(this);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,150));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(14);
// tv.setTextColor(Integer.parseInt("#D3D3D3"));
tv.setText(text);
row.addView(tv);
}
}
tableLayout.addView(row);

textviews in table.i want user input on those textviews on a submit button click

I want to set user input to the textviews in a tablelayout for a word game application.i am new to android please help me through this.
tl = (TableLayout)findViewById(R.id.table);
TableLayout.LayoutParams tablelparam = new TableLayout.LayoutParams(30,30);
for (int r = 1; r <=9; r++) {
r1= new TableRow(this);
r1.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
for (int c = 1; c<=5; c++) {
TextView txtview=new TextView(MainActivity.this);
txtview.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT, TableRow.LayoutParams.WRAP_CONTENT));
txtview.setId(counter);
counter++;
txtview.setText( +counter + inputWord);
r1.addView(txtview);
}
tl.addView(r1,new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT,TableLayout.LayoutParams.WRAP_CONTENT));
}
Submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ArrayList<String>words = new ArrayList<String>();
for (int j = 0; j < words.size(); j++) {
TextView txtview = new TextView(MainActivity.this);
txtview.setId(j);
txtview.setText("" + words.get(j));
txtview.getLayoutParams();
t3.setText(t3.getText() + " " + txtview.getText());
}
};
Set the onClickListener() for each TextView you instantiate inside your for loop.

How to display database table records using TableLayout

I followed the "How to get data from database in my android table view as columns" link to resolve my problem
but a blank screen appears without data. On clicking the button I have written code to fetch the records from MS SQL DB.
My XML, for layout purpose, activity_display_result.xml:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tab" >
</TableLayout>
And the code snippet from MainActivity.java:
#SuppressLint("NewApi") #Override
public void onCreate(Bundle b)
{
super.onCreate(b);
setContentView(R.layout.activity_main);
if( Build.VERSION.SDK_INT >= 9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
initilize();
button1.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
List <Map<String,String>> dataList = querySQL(e1.getText().toString(),e2.getText().toString(),e.getText().toString());
StringBuilder builder = new StringBuilder();
for (int i=0;i<dataList.size();i++)
{
Log.i("onClick Method()", "UserName : "+dataList.get(i).get("UserName"));
Log.i("onClick Method()", "Password : "+dataList.get(i).get("Password"));
builder.append(dataList.get(i).get("UserName")).append(";").
append(dataList.get(i).get("Password")).append("_");
}
builder.toString();
String st = new String(builder);
String[] rows =st.split("_");
setContentView(R.layout.activity_display_result);
TableLayout tableLayout =(TableLayout) findViewById(R.id.tab);
tableLayout.removeAllViews();
for(int i=0;i<rows.length;i++)
{
String row = rows[i];
TableRow tableRow = new TableRow(getApplicationContext());
tableRow.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
final String[] cols = row.split(";");
Log.i("MainActivity ","Column length :"+cols.length);
//Handler handler = null;
for (int j = 0; j < cols.length; j++)
{
final String col = cols[j];
TextView TextView11 = new TextView(getApplicationContext());
TextView11.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
TextView11.setTextColor(color.black);
//TextView11.setText(String.format("%7s", col));
TextView11.setText(col);
tableRow.addView(TextView11);
}
tableLayout.addView(tableRow);
setContentView(R.layout.activity_display_result);
}
}
});
}
Declaring all
public void declere()
{
e = (EditText)findViewById(R.id.editText3);
e1 = (EditText)findViewById(R.id.editText1);
e2 = (EditText)findViewById(R.id.editText2);
button1=(Button)findViewById(R.id.button1);
}
//initializing
public void initilize()
{
Log.i("initilize() Method", "initilize() Method is called..Now Calling declere() method");
declere();
Log.i("initilize() Method", "declere() method is called ");
Log.i("initilize() Method", "Before Calling CONN() method..");
connect=CONN("sa","C!#C2#!2","RequestCenter");
Log.i("initilize() Method", "CONN() method called Successfully..");
}
I also added one CONN method for getting connection. Can anyone help me to determine why the screen appears blank ?
You are calling setContentView(R.layout.activity_display_result) at the end of your onClick method, which will reset the view to the content of the xml, hence giving you a blank screen as defined in activity_display_result.xml. You need to remove that line and see if it works.
A couple of things:
You continue to reset the setContentView(R.layout.activity_display_result); many times (via the loop). Is there a a reason? You probably only have to set it once at the end once all your controls have been placed in the layout. I've moved it to where I think it should be in the code below. If that doesn't work, reconsider taking it out as mentioned above by 2Dee
A question for my own understanding: Why is col set to Final? Would that not prevent the variable from being assigned the next value in the cols array? Thanks!
for(int i=0;i<rows.length;i++){
String row = rows[i];
TableRow tableRow = new TableRow(getApplicationContext());
tableRow.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
final String[] cols = row.split(";");
Log.i("MainActivity ","Column length :"+cols.length);
//Handler handler = null;
for (int j = 0; j < cols.length; j++)
{
final String col = cols[j];
TextView TextView11 = new TextView(getApplicationContext());
TextView11.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
TextView11.setTextColor(color.black);
//TextView11.setText(String.format("%7s", col));
TextView11.setText(col);
tableRow.addView(TextView11);
}
tableLayout.addView(tableRow);
}
setContentView(R.layout.activity_display_result);

Print out ArrayList content in Android TableLayout

I have this ArrayList:
ArrayList<Double> debtList = datasource.debtList;
ArrayList<Double> feeList = datasource.feeList;
How would I print out these two Lists side by side (formatting doesn't matter) in a TableLayout in a loop? Here is layout:
TableLayout table = (TableLayout) findViewById(R.id.myTableLayout);
Ok, you have two arraylists debtList and feeList, I assume both the arraylist contains equal number of elements, now iterate through this list, Create Table Row add two textViews to table row, and add tablerow to the tableLayout, so you can do following:
ArrayList<Double> debtList = datasource.debtList;
ArrayList<Double> feeList = datasource.feeList;
TableLayout table = (TableLayout) findViewById(R.id.myTableLayout);
for(int i=0;i<debtList.size();i++)
{
TableRow row=new TableRow(this);
double debt = debtList.get(i);
double fee = feeList.get(i);
TextView tvDebt=new TextView(this);
tvDebt.setText(""+debt);
TextView tvFee=new TextView(this);
tvFee.setText(""+fee);
row.addView(tvDebt);
row.addView(tvFee);
table.addView(row);
}
I have found out the solution if the arrayLists is not of equal size.
Here is the logic which i have implemented:
Here is my activity:
public class TestStringActivity extends Activity {
private ArrayList<String> input1 = new ArrayList<String>();
private ArrayList<String> input2 = new ArrayList<String>();
private TableRow row;
private TableLayout inflate;
private TextView txtcol1, txtcol2;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Populating the arrayList
input1.add("1 ");
input1.add("2 ");
input1.add("3 ");
input2.add(" Red");
input2.add(" Blue");
input2.add(" Green");
input2.add(" White");
inflate = (TableLayout) TestStringActivity.this
.findViewById(R.id.mytable);
for (int i = 0, j = 0; i < input1.size() || j < input2.size();) {
row = new TableRow(TestStringActivity.this);
txtcol1 = new TextView(TestStringActivity.this);
if (input1.size() > i) {
if ((input1.get(i) != null)) {
txtcol1.setText(input1.get(i));
i++;
}
} else {
txtcol1.setText("");
}
row.addView(txtcol1);
txtcol2 = new TextView(TestStringActivity.this);
if ((input2.size() > j)) {
if (input2.get(j) != null) {
txtcol2.setText(input2.get(j));
j++;
}
} else {
txtcol2.setText("");
}
this.row.addView(txtcol2);
inflate.addView(row);
}
}
}
Here is my Table Layout main.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mytable"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</TableLayout>
Hope this helps if the arrayLists size are not of equal size.
Assuming the number of entries in the ArrayLists are equal to the number of cells in the TableLayout, you can try something like this:
int index = 0;
TableLayout tableLayout = findViewById(R.id.table_layout);
for(int n = 0, s = tableLayout.getChildCount(); n < s; ++n) {
double debt = debtList.get(index);
double fee = feeList.get(index);
TableRow row = (TableRow) tableLayout.getChildAt(n);
TextView cell = (TextView) row.findViewById(R.id.textview_cell);
name.setText("debt = " + debt + ", fee = " + fee);
index++;
}

Getting java.util.concurrent.RejectedExecutionException from asyncTask on android

I am reading a sqlite database into a tableLayout. I wan't to do this in a seperate thread instead of having a long wait with no ui updates. So I used an AsyncTask to do some of the work and publish the results. However only about 1/4th of the item in my list actually make it on to the TableLayout. It works fine without the AsyncTask. Most of the items on the list throw an error (which I caught) java.util.concurrent.RejectedExecutionException. I'm not sure why this is. Here is my code.
myDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");
Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);
c.moveToFirst();
if (c != null) {
int color = 0xFFdfe8ea;
this.startManagingCursor(c);
// Loop through all Results
do {
try{
MyAsyncTask aTask = new MyAsyncTask();
String[]strings= {c.getString(c.getColumnIndex("title")),c.getString(c.getColumnIndex("artist")),c.getString(c.getColumnIndex("time")),c.getString(c.getColumnIndex("album")),""+color};
aTask.execute(strings);
}catch(Exception e){
Log.w("****", e);
}
if (color == 0xFFdfe8ea) {
color = 0xFFf2f8fa;
} else {
color = 0xFFdfe8ea;
}
} while (c.moveToNext());
}
} catch (SQLException e) {
Log.e("****", e.toString());
} finally {
if (myDB != null) {
myDB.close();
}
}
and here is the AsyncTask
class MyAsyncTask extends AsyncTask<String, Void, View> {
#Override
protected View doInBackground(String... params) {
int color = Integer.parseInt(params[4]);
TableRow tr = new TableRow(MainActivity.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView space = new TextView(MainActivity.this);
space.setText("");
space.setBackgroundColor(color); //0xFFf2f8fa alternating
space.setSingleLine();
space.setPadding(2, 2, 2, 2);
space.setGravity(Gravity.LEFT);
space.setTextColor(0xFF000000);
space.setLayoutParams(new LayoutParams(
findViewById(R.id.spaceColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView title = new TextView(MainActivity.this);
title.setText(params[0]);
title.setBackgroundColor(color); //0xFFf2f8fa alternating
title.setSingleLine();
title.setPadding(2, 2, 2, 2);
title.setGravity(Gravity.LEFT);
title.setTextColor(0xFF000000);
title.setEllipsize(TruncateAt.END);
title.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView artist = new TextView(MainActivity.this);
artist.setText(params[1]);
artist.setBackgroundColor(color); //0xFFf2f8fa alternating
artist.setSingleLine();
artist.setPadding(2, 2, 2, 2);
artist.setGravity(Gravity.LEFT);
artist.setTextColor(0xFF000000);
artist.setEllipsize(TruncateAt.END);
artist.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView time = new TextView(MainActivity.this);
time.setText(params[2]);
time.setBackgroundColor(color); //0xFFf2f8fa alternating
time.setSingleLine();
time.setPadding(2, 2, 2, 2);
time.setGravity(Gravity.LEFT);
time.setTextColor(0xFF000000);
time.setLayoutParams(new LayoutParams(
findViewById(R.id.timeColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView album = new TextView(MainActivity.this);
album.setText(params[3]);
album.setBackgroundColor(color); //0xFFf2f8fa alternating
album.setSingleLine();
album.setPadding(2, 2, 2, 2);
album.setGravity(Gravity.LEFT);
album.setTextColor(0xFF000000);
album.setEllipsize(TruncateAt.END);
album.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Add Button to row. */
tr.addView(space);
tr.addView(title);
tr.addView(artist);
tr.addView(time);
tr.addView(album);
/* Add row to TableLayout. */
return tr;
}
#Override
protected void onPostExecute(View tr) {
((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
#Override
protected void onPreExecute() {
}
}
For reference this is how I fixed it.
class MyAsyncTask extends AsyncTask<Void, Song, Void> {
#Override
protected Void doInBackground(Void... params) {
SQLiteDatabase myDB = openOrCreateDatabase("DatabaseName", MODE_PRIVATE, null);
String TableName = "songs";
myDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");
Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);
c.moveToFirst();
int filepathIndex=c.getColumnIndex("filepath");
int titleIndex=c.getColumnIndex("title");
int artistIndex=c.getColumnIndex("artist");
int albumIndex=c.getColumnIndex("album");
int timeIndex=c.getColumnIndex("time");
int playcountIndex=c.getColumnIndex("playcount");
if (c != null) {
int color = 0xFFdfe8ea;
// this.startManagingCursor(c);
// Loop through all Results
do {
Song song = new Song(c.getString(filepathIndex),c.getString(titleIndex),c.getString(artistIndex),c.getString(albumIndex),c.getString(timeIndex),c.getInt(playcountIndex),color);
// Add to song the data from your cursor
publishProgress(song);
if (color == 0xFFdfe8ea) {
color = 0xFFf2f8fa;
} else {
color = 0xFFdfe8ea;
}
} while (c.moveToNext());
}
return null;
}
#Override
protected void onPostExecute(Void item) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Song... items) {
for (Song song : items) {
TableRow tr = new TableRow(MainActivity.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView space = new TextView(MainActivity.this);
space.setText("");
space.setBackgroundColor(song.color); //0xFFf2f8fa alternating
space.setSingleLine();
space.setPadding(2, 2, 2, 2);
space.setGravity(Gravity.LEFT);
space.setTextColor(0xFF000000);
space.setLayoutParams(new LayoutParams(
findViewById(R.id.spaceColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView title = new TextView(MainActivity.this);
title.setText(song.title);
title.setBackgroundColor(song.color); //0xFFf2f8fa alternating
title.setSingleLine();
title.setPadding(2, 2, 2, 2);
title.setGravity(Gravity.LEFT);
title.setTextColor(0xFF000000);
title.setEllipsize(TruncateAt.END);
title.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView artist = new TextView(MainActivity.this);
artist.setText(song.artist);
artist.setBackgroundColor(song.color); //0xFFf2f8fa alternating
artist.setSingleLine();
artist.setPadding(2, 2, 2, 2);
artist.setGravity(Gravity.LEFT);
artist.setTextColor(0xFF000000);
artist.setEllipsize(TruncateAt.END);
artist.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView time = new TextView(MainActivity.this);
time.setText(song.time);
time.setBackgroundColor(song.color); //0xFFf2f8fa alternating
time.setSingleLine();
time.setPadding(2, 2, 2, 2);
time.setGravity(Gravity.LEFT);
time.setTextColor(0xFF000000);
time.setLayoutParams(new LayoutParams(
findViewById(R.id.timeColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView album = new TextView(MainActivity.this);
album.setText(song.album);
album.setBackgroundColor(song.color); //0xFFf2f8fa alternating
album.setSingleLine();
album.setPadding(2, 2, 2, 2);
album.setGravity(Gravity.LEFT);
album.setTextColor(0xFF000000);
album.setEllipsize(TruncateAt.END);
album.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Add Button to row. */
tr.addView(space);
tr.addView(title);
tr.addView(artist);
tr.addView(time);
tr.addView(album);
// Add the row to the table
((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
}
}
The reason you are seeing this RejectedExceutionException is almost certainly because you are submitting too many requests.
I just went into the code of AsyncTask and I noticed:
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
/**
* An {#link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
That will build a bounded LinkedBlockingQueue. Up to 10 elements for the bound. The
MAXIMUM_POOL_SIZE I saw was 128 (which means if needed the Executor will create 128 threads at most).
Once you exceed the 128 thread and submit to a new MyTask instance with a queue depth of 10 you will get a RejectedExecutionException. This exception is thrown when you saturate all available threads and there is no more room on the queue.
You can easily confirm this by getting a thread-dump when the RejectedExecution occurs.
Basically, you can submit 138 MyTask's at any particular time but once you submit 139+ at the same time (not within the life time of the app) you will run into this issue
Edit: I went through the code more, and the most recent version (actually since Jan 16, 2011) this error should never happen.
With any version older then that you will run into this issue.
In short, if you upgrade you version this issue will go away, however each task will be executed serially and not concurrently.
If you want to do it using an AsyncTask, consider using publishProgress(), that way each item will be added as it is fetched from the database. This way:
NOTE: Consider that Song is a class with name, album, artist and time attributes.
class MyAsyncTask extends AsyncTask<Void, Song, Void> {
#Override
protected Void doInBackground(Void... params) {
myDB.execSQL("CREATE TABLE IF NOT EXISTS "
+ TableName
+ " (_id INTEGER PRIMARY KEY, filepath TEXT UNIQUE, title TEXT, artist TEXT, album TEXT, time TEXT, playcount NUMERIC);");
Cursor c = myDB.rawQuery("SELECT * FROM " + TableName, null);
c.moveToFirst();
if (c != null) {
int color = 0xFFdfe8ea;
this.startManagingCursor(c);
// Loop through all Results
do {
Song song = new Song();
// Add to song the data from your cursor
publishProgress(song);
} while (c.moveToNext());
}
return null;
}
#Override
protected void onPostExecute(Void item) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Song... items) {
for (Song song : items) {
TableRow tr = new TableRow(MainActivity.this);
tr.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
TextView space = new TextView(MainActivity.this);
space.setText("");
space.setBackgroundColor(color); //0xFFf2f8fa alternating
space.setSingleLine();
space.setPadding(2, 2, 2, 2);
space.setGravity(Gravity.LEFT);
space.setTextColor(0xFF000000);
space.setLayoutParams(new LayoutParams(
findViewById(R.id.spaceColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView title = new TextView(MainActivity.this);
title.setText(song.getTitle());
title.setBackgroundColor(color); //0xFFf2f8fa alternating
title.setSingleLine();
title.setPadding(2, 2, 2, 2);
title.setGravity(Gravity.LEFT);
title.setTextColor(0xFF000000);
title.setEllipsize(TruncateAt.END);
title.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView artist = new TextView(MainActivity.this);
artist.setText(song.getArtist());
artist.setBackgroundColor(color); //0xFFf2f8fa alternating
artist.setSingleLine();
artist.setPadding(2, 2, 2, 2);
artist.setGravity(Gravity.LEFT);
artist.setTextColor(0xFF000000);
artist.setEllipsize(TruncateAt.END);
artist.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Create a Button to be the row-content. */
TextView time = new TextView(MainActivity.this);
time.setText(song.getTime());
time.setBackgroundColor(color); //0xFFf2f8fa alternating
time.setSingleLine();
time.setPadding(2, 2, 2, 2);
time.setGravity(Gravity.LEFT);
time.setTextColor(0xFF000000);
time.setLayoutParams(new LayoutParams(
findViewById(R.id.timeColumn).getWidth(),
LayoutParams.WRAP_CONTENT));
/* Create a Button to be the row-content. */
TextView album = new TextView(MainActivity.this);
album.setText(song.getAlbum());
album.setBackgroundColor(color); //0xFFf2f8fa alternating
album.setSingleLine();
album.setPadding(2, 2, 2, 2);
album.setGravity(Gravity.LEFT);
album.setTextColor(0xFF000000);
album.setEllipsize(TruncateAt.END);
album.setLayoutParams(new LayoutParams(
0,
LayoutParams.WRAP_CONTENT, 1));
/* Add Button to row. */
tr.addView(space);
tr.addView(title);
tr.addView(artist);
tr.addView(time);
tr.addView(album);
// Add the row to the table
((TableLayout) findViewById(R.id.tableLayout)).addView(tr, new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
}
}
I believe you understood the concept behind AsyncTask wrongly, I strongly suggest you reread its documentation at Android Developers as its concept is a bit tricky to understand but very powerfull when you do so. As Romain Guy commented on your answer you can only execute UI code on the onPreExecute(), onProgressUpdate() and onPostExecute() methods.
I dont think you need to create one AsyncTask for that. You are not fetching anything from the network or downloading images. Its just standard loading.
I would limit the result in the SQL with 'limit'.
Also, you are doing that inside an adapter right? Because I think you are adding everything to the list, where you should create a listview in your layout and set an Adapter. Maybe extending BaseAdapter.
Every adapter has a convenient method called getView that will get called only when it is visible and should help with your problem.
This is an example of an adapter:
public class MyAdapter extends BaseAdapter {
private Context context = null;
private Cursor cursor;
public MyAdapter(Context context){
this.context = context;
SQLiteDatabase db = DatabaseHelper.getInstance(context).getReadableDatabase();
this.cursor = db.query("YOUR QUERY");
}
#Override
public int getCount() {
return this.cursor.getCount();
}
public Cursor getCursor() {
return cursor;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout row;
try {
cursor.moveToPosition(position);
if (convertView == null) {
row = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.myRowLayout, parent, false);
} else {
row = (LinearLayout) convertView;
}
TextView name = (TextView) row.findViewById(R.id.myLayoutId);
name.setText(cursor.getString(cursor.getColumnIndex("your column")));
} catch (Exception e) {
row = null;
Log.e(LOG_TAG, "" + e.getMessage());
e.printStackTrace();
}
return row;
}
#Override
public MoneyCurrency getItem(int position) {
this.cursor.moveToPosition(position);
long id = this.cursor.getLong(this.cursor.getColumnIndex("your column id"));
return new Object.read(id, context, null); //Return whatever you want to show in that row. This is used if you want to use onClick listeners or menus
}
#Override
public long getItemId(int position) {
this.cursor.moveToPosition(position);
return this.cursor.getLong(this.cursor.getColumnIndex("your id column"));
}
}

Categories

Resources