This question already has answers here:
The application may be doing too much work on its main thread
(21 answers)
Closed 1 year ago.
I have a block of code to load a table view. But for large data, my app is crashing. I want to fix that and also want to show a progress bar while loading the table view data. I tried with the AsyncTask but it is showing Skipped 98 frames! The application may be doing too much work on its main thread.
My onCreate code (Updated): -
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sheet);
myDb = new DBHelper(this);
loadIntentInputs();
setToolbar();
new MyWorker(this).execute();
}
My AsyncTask code (Updated): -
public class MyWorker extends AsyncTask < String , Context , Void > {
private Context context ;
private ProgressDialog progressDialog;
public MyWorker (Context context) {
this.context = context ;
progressDialog = new ProgressDialog ( context ) ;
progressDialog.setCancelable ( false ) ;
progressDialog.setMessage ( "Retrieving data..." ) ;
progressDialog.setTitle ( "Please wait" ) ;
progressDialog.setIndeterminate ( true ) ;
}
# Override
protected void onPreExecute ( ) {
progressDialog.show () ;
}
# Override
protected Void doInBackground ( String ... params ) {
runOnUiThread(new Runnable() {
#Override
public void run() {
showAttendanceTable();
}
});
return null ;
}
# Override
protected void onPostExecute ( Void result ) {
if(progressDialog != null && progressDialog.isShowing()){
progressDialog.dismiss ( ) ;
}
}
}
showAttendanceTable method code (Updated): -
private void showAttendanceTable() {
TableLayout tableLayout = findViewById(R.id.table_layout);
int day_in_month = getDayInMonth(month_year);
int row_size = sid_array.length+1;
TableRow[] rows = new TableRow[row_size];
TextView[] rolls_tv = new TextView[row_size];
TextView[] names_tv = new TextView[row_size];
TextView[][] status_tv = new TextView[row_size][day_in_month+1];
for (int i = 0; i < row_size; i++) {
rolls_tv[i] = new TextView(this);
names_tv[i] = new TextView(this);
for (int j = 1; j <= day_in_month; j++) {
status_tv[i][j] = new TextView(this);
}
}
// for excel file
HSSFSheet hssfSheet = null;
try {
hssfSheet = hssfWorkbook.createSheet(month_year);
} catch (IllegalArgumentException e){
e.printStackTrace();
}
HSSFRow hssfRow;
// setting 1st row
rolls_tv[0].setText("Roll");
names_tv[0].setText("Name");
// setting excel file
hssfRow = hssfSheet.createRow(0);
hssfRow.createCell(0).setCellValue("Roll");
hssfRow.createCell(1).setCellValue("Name");
rolls_tv[0].setTextSize(1,22);
names_tv[0].setTextSize(1,22);
rolls_tv[0].setTypeface(rolls_tv[0].getTypeface(), Typeface.BOLD);
names_tv[0].setTypeface(names_tv[0].getTypeface(), Typeface.BOLD);
rolls_tv[0].setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
names_tv[0].setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
rolls_tv[0].setTextColor(Color.parseColor("#FF000000"));
names_tv[0].setTextColor(Color.parseColor("#FF000000"));
for (int i = 1; i <=day_in_month ; i++) {
String date = String.valueOf(i);
if(i<10) date = "0"+date;
status_tv[0][i].setText(date);
// setting excel file
hssfRow.createCell(i+1).setCellValue(date);
status_tv[0][i].setTextSize(1,22);
status_tv[0][i].setTypeface(status_tv[0][i].getTypeface(), Typeface.BOLD);
status_tv[0][i].setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
status_tv[0][i].setTextColor(Color.parseColor("#FF000000"));
}
// setting rows after 1st row
for (int i = 1; i < row_size ; i++) {
rolls_tv[i].setText(roll_array[i-1]);
names_tv[i].setText(name_array[i-1]);
// setting excel file
hssfRow = hssfSheet.createRow(i);
hssfRow.createCell(0).setCellValue(roll_array[i-1]);
hssfRow.createCell(1).setCellValue(name_array[i-1]);
rolls_tv[i].setTextSize(1,20);
names_tv[i].setTextSize(1,20);
rolls_tv[i].setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
names_tv[i].setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
rolls_tv[i].setTextColor(Color.parseColor("#FF000000"));
names_tv[i].setTextColor(Color.parseColor("#FF000000"));
int count=0;
for (int j = 1; j <=day_in_month ; j++) {
String day = String.valueOf(j);
String month = month_year.substring(0,3);
String year = month_year.substring(4,8);
String status = myDb.getStatus(sid_array[i-1],day+" "+month+" "+year);
if (status!=null && status.equals("A")) {
status_tv[i][j].setText(status);
status_tv[i][j].setBackgroundColor(Color.parseColor("#EF9A9A"));
// setting excel file
hssfRow.createCell(j+1).setCellValue(status);
} else if (status!=null && status.equals("P")) {
status_tv[i][j].setText(String.valueOf(++count));
status_tv[i][j].setBackgroundColor(Color.parseColor("#A5D6A7"));
// setting excel file
hssfRow.createCell(j+1).setCellValue(String.valueOf(count));
}
status_tv[i][j].setTextSize(1,20);
status_tv[i][j].setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
status_tv[i][j].setTextColor(Color.parseColor("#FF000000"));
}
}
for (int i = 0; i < row_size; i++) {
rows[i] = new TableRow(this);
rolls_tv[i].setPadding(20,12,20,12);
names_tv[i].setPadding(20,12,20,12);
if (i==0) {
rows[i].setBackgroundColor(Color.parseColor("#FFD400"));
} else if(i%2==0) {
rows[i].setBackgroundColor(Color.parseColor("#EEEEEE"));
} else {
rows[i].setBackgroundColor(Color.parseColor("#E4E4E4"));
}
rows[i].addView(rolls_tv[i]);
rows[i].addView(names_tv[i]);
for (int j = 1; j <=day_in_month ; j++) {
status_tv[i][j].setPadding(20,12,20,12);
rows[i].addView(status_tv[i][j]);
}
tableLayout.addView(rows[i]);
}
tableLayout.setShowDividers(TableLayout.SHOW_DIVIDER_MIDDLE);
}
The problem is you are running new thread on your doInBackground method and you have placed your showAttendanceTable() code inside runOnUiThread() which is causing too many work to consume main thread.Just copy paste the below code, replace it with your doInBackground() method and everything will work fine.
protected Void doInBackground ( String ... params ) {
showAttendanceTable();
}
return null ;
}
Copy this much part of your code from showAttendanceTable() to onPreExecute() method:
TableLayout tableLayout = findViewById(R.id.table_layout);
int day_in_month = getDayInMonth(month_year);
int row_size = sid_array.length+1;
TableRow[] rows = new TableRow[row_size];
TextView[] rolls_tv = new TextView[row_size];
TextView[] names_tv = new TextView[row_size];
TextView[][] status_tv = new TextView[row_size][day_in_month+1];
for (int i = 0; i < row_size; i++) {
rolls_tv[i] = new TextView(this);
names_tv[i] = new TextView(this);
for (int j = 1; j <= day_in_month; j++) {
status_tv[i][j] = new TextView(this);
}
}
Related
I want to find Duplicate Images from External Storage.
In my current solution I successfully find Duplicates.
But when the data is large, the processing time long.
My current design first gets all images, then loops to find duplicates.
Here is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AllImages_1 = getImagesList(); // AllImages_1 is a array list
}
private ArrayList<File> getImagesList() {
Uri uri;
Cursor cursor;
int column_index_data;
ArrayList<File> listOfAllImages = new ArrayList<>();
String absolutePathOfImage = null;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
cursor = MainActivity.this.getContentResolver().query(uri, projection, null,
null, null);
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
listOfAllImages.add(new File(absolutePathOfImage));
}
return listOfAllImages;
}
below code is find Dulpicate
public void CheckedDuplicateImage() {
int Group = 1;
arrayList.clear();
ArrayList<String> grpind = new ArrayList<>();
for (int i = 0; i < AllImages_1.size(); i++) {
ArrayList<VideoDataClass> group = new ArrayList<>();
duplicate = false;
boolean duplicate_I = false;
if (grpind.contains(String.valueOf(i))) {
continue;
}
for (int j = 0; j < AllImages_1.size(); j++) {
if (i != j && (AllImages_1.get(i).length() == AllImages_1.get(j).length() ||
AllImages_1.get(i).getName() == AllImages_1.get(j).getName())) {
if (!duplicate_I) {
group.add(OriginalFile(AllImages_1.get(i)));
duplicate_I = true;
}
duplicate = true;
group.add(DuplicateFile(AllImages_1.get(j)));
grpind.add(String.valueOf(j));
}
}
if (duplicate) {
Duplicate=true;
String Header = "Group" + Group;
modelClass = new ModelClass(group, Header);
arrayList.add(modelClass);
Group++;
}
}
}
My question: **is there an alternative solution that will achieve the same result in less time?**
I want to add layout dynamically in my android app using java code only, not using XML code. Kindly help me with this. Advance thank you.
with using this code I had done this :
public void makeSeat()
{
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(3,3,3,3);
GridLayout gl = (GridLayout) findViewById(R.id.grid_main);
int column = 4;
int row = 5;
int i_total = 4*5;
int i_busSeatNo = 1;
gl.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gl.setColumnCount(column);
gl.setRowCount(row + 1);
CheckBox btn;
for(int i =0, c = 0, r = 1; i < i_total; i++, c++)
{
if(c == column)
{
c = 0;
r++;
i_busSeatNo++;
}
if (r == c+1 ){
i_busSeatNo = r;
}
btn = new CheckBox(this);
btn.setGravity(Gravity.CENTER);
btn.setBackgroundResource(R.drawable.chbox);
btn.setButtonDrawable(R.drawable.chbox);
btn.setHeight(val_seat);
btn.setWidth(val_seat);
btn.setText(""+i_busSeatNo); //(r+" "+c); //r+" "+c
int cnt = Integer.parseInt(r+""+c);
btn.setId(cnt);
final CheckBox finalBtn = btn;
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(DynamicBus.this,
"id: " + finalBtn.getId() + "\nNo: " + finalBtn.getText(),
Toast.LENGTH_SHORT).show();
}
});
if(c != column-1) {
i_busSeatNo = i_busSeatNo+5;
}
gl.addView(btn, i);
GridLayout.LayoutParams param =new GridLayout.LayoutParams();
param.height = val_seat;
param.width = val_seat;
param.rightMargin = 7;
param.topMargin = 7;
param.setGravity(Gravity.CENTER);
param.columnSpec = GridLayout.spec(c);
if (r==1)
param.rowSpec = GridLayout.spec(r,1);
btn.setLayoutParams (param);
}
}
Output :
what I get :
https://i.stack.imgur.com/FqynC.png
what I want :
https://i.stack.imgur.com/QZCTI.png
Hello fellow stackoverflowers,
i just wrote this code to populate a tablelayout inside my activity_customer layout. For some reason in runs through without throwing the slightest error, but at the end of "populateView" the application just stops/crashes.
I tried some many things I found via google/stackoverflow, but none seems to work. I hope someone can help me find why the app stops.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_customer);
populateView(DataClass.getReturnData());
}
private void populateView(String[] Array){
int len = Array.length;
TableLayout tab = (TableLayout) findViewById(R.id.table);
if (len != 0){
for (int i = 0; i <= len - 1; i++) {
TableRow row = new TableRow(this);
TextView tvName = new TextView(this);
tvName.setText("" + Array[i]);
System.out.println(Array[i]);
tab.addView(row);
}
}
}
Thanks in advance,
Soulrox
Here is a complete example:
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
String[] row = { "ROW1", "ROW2", "Row3", "Row4", "Row 5", "Row 6",
"Row 7"
};
String[] column = { "COLUMN1", "COLUMN2", "COLUMN3", "COLUMN4",
"COLUMN5", "COLUMN6"
};
int rl=row.length;
int cl=column.length;
ScrollView sv = new ScrollView(this);
TableLayout tableLayout = createTableLayout(row, column,rl, cl);
HorizontalScrollView hsv = new HorizontalScrollView(this);
hsv.addView(tableLayout);
sv.addView(hsv);
setContentView(sv);
}
private TableLayout createTableLayout(String [] rv, String [] cv,int rowCount, int columnCount)
{
// 1) Create a tableLayout and its params
TableLayout.LayoutParams tableLayoutParams = new TableLayout.LayoutParams();
TableLayout tableLayout = new TableLayout(this);
tableLayout.setBackgroundColor(Color.BLACK);
// 2) create tableRow params
TableRow.LayoutParams tableRowParams = new TableRow.LayoutParams();
tableRowParams.setMargins(1, 1, 1, 1);
tableRowParams.weight = 1;
for (int i = 0; i < rowCount; i++)
{
// 3) create tableRow
TableRow tableRow = new TableRow(this);
tableRow.setBackgroundColor(Color.BLACK);
for (int j= 0; j < columnCount; j++)
{
// 4) create textView
TextView textView = new TextView(this);
// textView.setText(String.valueOf(j));
textView.setBackgroundColor(Color.WHITE);
textView.setGravity(Gravity.CENTER);
String s1 = Integer.toString(i);
String s2 = Integer.toString(j);
String s3 = s1 + s2;
int id = Integer.parseInt(s3);
Log.d("TAG", "-___>"+id);
if (i ==0 && j==0)
{
textView.setText("0==0");
}
else if(i==0)
{
Log.d("TAAG", "set Column Headers");
textView.setText(cv[j-1]);
}
else if( j==0)
{
Log.d("TAAG", "Set Row Headers");
textView.setText(rv[i-1]);
}
else
{
textView.setText(""+id);
// check id=23
if(id==23)
{
textView.setText("ID=23");
}
}
// 5) add textView to tableRow
tableRow.addView(textView, tableRowParams);
}
// 6) add tableRow to tableLayout
tableLayout.addView(tableRow, tableLayoutParams);
}
return tableLayout;
}
}
Output:
If I clear the list view, the listview will gone.The list view will fetch data from the for loop.
Workarounds:
Putting setdaylist.clear() inside the any loop will clear the all listview and display only one list item.
Setting it at the top of method will erase all the listview, any solution?
Code:
public void onDataGotOnline(JSONObject response) {
DateTime today = new DateTime().withTimeAtStartOfDay();
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
try {
JSONArray currentData = response.getJSONArray("list");
// setdaylist.clear();
for (int i = 1; i < 5; i++) {
DateTime tomorow = today.plusDays(i).withTimeAtStartOfDay();
String dtStr = fmt.print(tomorow);
int info = 0;
for(; info<currentData.length();info++ ){
JSONObject managedata = currentData.getJSONObject(info);
String time= managedata.getString("dt_txt");
if(time.equals(dtStr)){
int getResult=info+8;
double[] arrayAverageTemp = new double[8];
double[] arrayMaxTemp = new double[8];
double[] arrayMinTemp = new double[8];
int[] arrayWheaterId = new int[8];
for (int a = info; a < getResult; a++) {
JSONObject datalist = currentData.getJSONObject(i);
JSONArray weatherdata = datalist.getJSONArray("weather");
JSONObject weatherdata2 = weatherdata.getJSONObject(weatherdata.length() - 1);
int id = weatherdata2.getInt("id");
JSONObject weather = datalist.getJSONObject("main");
double avg_temp = weather.getDouble("temp");
double max_temp = weather.getDouble("temp_max");
double min_temp = weather.getDouble("temp_min");
arrayWheaterId[a-info]=id;
arrayAverageTemp[a-info]=avg_temp;
arrayMaxTemp[a-info]=max_temp;
arrayMinTemp[a-info]=min_temp;
}
ManageData manageData = new ManageData();
double max = manageData.findMax(arrayMaxTemp);
double min = manageData.findMin(arrayMinTemp);
WheatherData day = new WheatherData();
day.setDay("sunday");
// int image = convert.covertImage(icon);
day.setImage(R.drawable.ic_image_01d);
day.setDescrption("asdasd");
day.setAvgTemp("14 °c");
day.setMaxTemp(max+ "°c");
day.setMinTemp(min+ "°c");
setdaylist.add(day);
adapter.notifyDataSetChanged();
// findMax(arrayMaxTemp);
//findMin(arrayMinTemp);
//findID(arrayWheaterId);
//findaverage(arrayAverageTemp);
}
}
}
}
catch (JSONException e){
}
}
From the discussion above.
Issue was due to the caching problem in Android studio.
Cleaning Project and Building it removes the existing cache.
By which the setdaylist before the for loop shown below works as expected.
public void onDataGotOnline(JSONObject response) {
...
try {
...
setdaylist.clear();
for (int i = 1; i < 5; i++) {
...
for(; info<currentData.length();info++ ){
...
if(time.equals(dtStr)){
...
setdaylist.add(day);
...
}
}
}
}
catch (JSONException e){}
}
I have created dynamically edittext on my android application like below:
protected void onCreate(Bundle savedInstanceState) {
RelativeLayout layout = (RelativeLayout) findViewById(R.id.linearLayout1);
final EditText[] Et = new EditText[10];
int prevTextViewId = 0;
int add = 0;
int add1 = 0;
for (int a = 0; a < Arr.length; a++) {
Et[a] = new EditText(this);
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
(int) LayoutParams.WRAP_CONTENT,
(int) LayoutParams.WRAP_CONTENT);
param.leftMargin = 25;
param.topMargin = (a + 1) * (100 + add1);
Et[a].setPadding(5, 23, 5, 5);
Et[a].setLayoutParams(param);
Et[a].setSingleLine(false);
Et[a].setHorizontalScrollBarEnabled(false);
Et[a].setWidth(280);
Et[a].getText().toString();
layout.addView(Et[a]);
add = add + 25;
add1 = add1 + 15;
}
}
And I want to get text from dynamically created edittext into a button like below:
btn_doneAnswer = (Button) findViewById(R.id.btn_doneAnswer);
btn_doneAnswer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
for (int a = 0; a < Arr.length; a++) {
Et[a] = new EditText(this);
String text += Et[a].getText().toString();
}
Bundle bundle = new Bundle();
Intent i_backToAddItem = new Intent(
AnswerActivityMultiText.this,
QuestionActivityDynamic.class);
bundle.putString("text", text);
bundle.putString("MultiQues", MultiQues);
i_backToAddItem.putExtras(bundle);
startActivity(i_backToAddItem);
}
});
But I am getting error below in the button onclick method at this line Et[a] = new EditText(this);:
The constructor EditText(new View.OnClickListener(){}) is undefined
another below error at this line += in the button onclick method:
Syntax error on token "+=", = expected
Kindly suggest me how I am getting text from dynamically created edittext into a button.
Waiting for reply.
Thanks
you dont have to initialize the EditText again in the onClick. You should directly use the EditText object to get the text. So the line
Et[a] = new EditText(this);
is not required at all!
And for the error with '+=' operator, you are declaring the string and using the operator(+=) in one line. you have to split up the the declaration part out of the for loop and then use '+='. Here's the complete code :
btn_doneAnswer = (Button) findViewById(R.id.btn_doneAnswer);
btn_doneAnswer.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String text;
for (int a = 0; a < Arr.length; a++) {
text += Et[a].getText().toString();
}
Bundle bundle = new Bundle();
Intent i_backToAddItem = new Intent(
AnswerActivityMultiText.this,
QuestionActivityDynamic.class);
bundle.putString("text", text);
bundle.putString("MultiQues", MultiQues);
i_backToAddItem.putExtras(bundle);
startActivity(i_backToAddItem);
}
});
Your problem is in this lines:
for (int a = 0; a < Arr.length; a++) {
Et[a] = new EditText(this);
String text += Et[a].getText().toString();
}
In this line:
Et[a] = new EditText(this);
this is the onClickListener object, you must have class.this (where class is the class name of file that this code is created).
In this other line:
String text += Et[a].getText().toString();
You always create a new String, and instead of created, you make an add. It is a Java concept fail.
You must do this:
String text = "";
for (int a = 0; a < Arr.length; a++) {
Et[a] = new EditText(class_name.this);
text += Et[a].getText().toString();
}