#java #android #asynchronous #dialog
#java #Android #асинхронный #диалоговое окно
Вопрос:
Я пытаюсь обновить сообщение в моем диалоговом окне оповещения. Я хочу, чтобы в диалоговом окне отображался обновленный процент завершения графика.
Пожалуйста, подождите… Графики загружаются…
0% завершено
Я выяснил, как получить процент от каждой итерации цикла, мне сложно обновить диалоговое окно до правильного процента. Заранее спасибо!!!!
// мой объект xml textview
<TextView
android:id="@ id/percentloaded"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The graphs are loading...n0% Completed"
android:layout_gravity="right"
android:visibility="invisible"
android:textColor="#FFFFFF" />
// как я вызываю асинхронность внутри моей функции создания
new MyAsync().execute();
//мой onCreate()
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network_showcharts);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// fun little snippet that prevents users from taking screenshots
// on ICS devices :-)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
//Toast.makeText(NetworkAllInformation_ShowChart.this, "Please wait for graphs to finish loading", Toast.LENGTH_SHORT).show();
progressDialog = new ProgressDialog(NetworkAllInformation_ShowChart.this);
cycleDate = (TextView) findViewById(R.id.CycleDateAnswer);
cycleDay = (TextView) findViewById(R.id.CycleDayAnswer);
cycleDailyUsage = (TextView) findViewById(R.id.CycleUsageAnswer);
cycleOverallUsage = (TextView) findViewById(R.id.TotalUsageAnswer);
percentLoaded = (TextView) findViewById(R.id.percentloaded);
stringofZero = "0";
plot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
alertDialogBuilder = new AlertDialog.Builder(this);
final Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
currentDate = (month 1) "-" day "-" year;
theNumberOfDaysToCompare = day;
intObj = new Integer(theNumberOfDaysToCompare);
intNumberOfMaxGBsAccepted = 0;
numObj = (Number)intObj;
series1Numbers = new Number[(Integer) numObj];
series2Numbers = new Number[(Integer) numObj];
series3Numbers = new Number[(Integer) numObj];
handler = new Handler();
ParseQuery<ParseObject> query0 = ParseQuery.getQuery("ClientCompanyInfo");
query0.whereEqualTo("SiteID", ShowSatellitesActivity.IDchosen);
query0.addAscendingOrder("SiteID");
query0.setLimit(1000);
query0.selectKeys(Arrays.asList("UsagePlan"));
List<ParseObject> results0 = null;
try {
results0 = query0.find();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("query0 size: " results0.size());
for (ParseObject data : results0) {
// This does not require a network access.
Integer.parseInt(data.getString("UsagePlan"));
System.out.println("the usage plan is: " Integer.parseInt(data.getString("UsagePlan")) );
if(Integer.parseInt(data.getString("UsagePlan")) >=1 )
{
System.out.println("The usage plan is a set number");
intNumberOfMaxGBsAccepted = Integer.parseInt(data.getString("UsagePlan"));
} //ends if
}//ends for loop
new MyAsync().execute();
sum = 0;
} //ends on create
// моя асинхронная задача
private static class MyAsync extends AsyncTask <Void, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// set title
alertDialogBuilder.setTitle("Please wait...");
alertDialogBuilder.setCancelable(false);
// set dialog message
alertDialogBuilder.setMessage(percentLoaded.getText());
// create alert dialog
alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
protected static void onProgressUpdate(Integer progress) {
alertDialog.setMessage("The graphs are loading...n" progress[0] "% Completed");
alertDialog.dismiss();
System.out.println("onProgressUpdate: " progress[0]);
}
protected void onPostExecute(String result) {
System.out.println("onPostExecute: " result);
alertDialog.setMessage("The graphs are loading...n" result "% Completed");
}
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
incrementor = 0;
for ( int i = 0; i<day; i ){
//get information about the user
ParseQuery<ParseObject> query = ParseQuery.getQuery("UsageCalculator");
query.whereEqualTo("SiteID", ShowSatellitesActivity.IDchosen);
query.addAscendingOrder("SiteID");
query.setLimit(1000);
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject dailyUsage, ParseException e) {
if (e == null) {
dayString = (1 incrementor);
System.out.println("Day number: " Integer.toString(dayString));
getThePercent = Integer.toString((int) ((100 / (float) day) * dayString));
System.out.println(getThePercent);
Integer percentInt = Integer.valueOf((100 /day) * dayString);
try{
publishProgress(percentInt);
Thread.sleep(1000);
} catch(Exception e1){
e1.printStackTrace();
}
//start
ParseQuery<ParseObject> query2 = ParseQuery.getQuery("UsageCalculator");
query2.whereEqualTo("monthString", String.valueOf(month 1)); //current month
query2.whereEqualTo("SiteID", dailyUsage.getString("SiteID")); //the selected ID
query2.whereEqualTo("yearString", String.valueOf(year)); //current year
query2.whereEqualTo("dayString", Integer.toString(dayString)); //incremented through to have every day
query2.addAscendingOrder("SiteID");
query2.setLimit(1000);
query2.selectKeys(Arrays.asList("dataUsedString", "usageDate")); //take the information out of the date and usage columns
List<ParseObject> results = null;
try {
results = query2.find();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("query8 size: " results.size());
for (ParseObject data : results) {
// This does not require a network access.
myArray.add(data.getString("dataUsedString"));
}
//the last day reached
if(myArray.size() == day-1){
alertDialog.dismiss();
plot.clear(); //erase the old plot
updateGraphValues(); //get values of graph
updateGraphBackground(); //set the values to the graph
plot.redraw(); //redraw the plot with the correct values
}
incrementor ;
} //if the exception handler is null
else {
Log.d("showChart", "Error: " e.getMessage()); //if their is an exception
}
} //ends the done
}); //ends the query
} //ends the for loop
return "";
}
}
// другие вызовы функций
private static void updateGraphValues() {
for (int i = 0; i<myArray.size(); i ){
usageValue = Double.parseDouble(myArray.get(i));
//daily usage array
series2Numbers[i] = usageValue;
//total usage sumation array
series1Numbers[i] = (usageValue increasingSum);
//the max value
series3Numbers[i] = intNumberOfMaxGBsAccepted;
vector.add((double) i);
vector.add(Math.sin(i));
//keeping a running sum
if(usageValue!=0) { increasingSum= increasingSum usageValue; }
}
increasingSum = 0;
} // ends updating the graph value function
private static void updateGraphBackground() {
// Turn the above arrays into XYSeries':
series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), // SimpleXYSeries takes a List so turn our array into a List
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
"Total"); // Set the display title of the series
// same as above
series2 = new SimpleXYSeries(Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Daily");
series3 = new SimpleXYSeries(Arrays.asList(series3Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Max");
series1Format = new LineAndPointFormatter(Color.rgb(51, 51, 255), 0, Color.rgb(51, 153, 255), null);
series1Format.getFillPaint().setStrokeJoin(Paint.Join.ROUND);
series1Format.getFillPaint().setStrokeCap(Paint.Cap.ROUND);
series1Format.getFillPaint().setPathEffect(new CornerPathEffect(10) );
series1Format.getFillPaint().setAntiAlias(true);
series1Format.getFillPaint().setStrokeWidth(8);
// same as above:
//daily green
series2Format = new LineAndPointFormatter(Color.rgb(51, 255, 153), 0, Color.rgb(153, 255, 204), null);
series2Format.getFillPaint().setStrokeJoin(Paint.Join.ROUND);
series2Format.getFillPaint().setStrokeCap(Paint.Cap.ROUND);
series2Format.getFillPaint().setPathEffect(new CornerPathEffect(10) );
series2Format.getFillPaint().setAntiAlias(true);
series2Format.getFillPaint().setStrokeWidth(8);
series3Format = new LineAndPointFormatter(Color.rgb(255, 51, 51), 0, 0, null);
series3Format.getFillPaint().setStrokeJoin(Paint.Join.ROUND);
series3Format.getFillPaint().setStrokeCap(Paint.Cap.ROUND);
series3Format.getFillPaint().setPathEffect(new CornerPathEffect(10) );
series3Format.getFillPaint().setAntiAlias(true);
series3Format.getFillPaint().setStrokeWidth(8);
// add a new series' to the xyplot:
plot.addSeries(series1, series1Format); //this one has to be first to that the domain and range can be found for this series
plot.addSeries(series2, series2Format);
plot.addSeries(series3, series3Format);
// reduce the number of range labels
plot.setTicksPerRangeLabel(1);
plot.getGraphWidget().setDomainLabelOrientation(45);
plot.calculateMinMaxVals();
minXy=new PointF(plot.getCalculatedMinX().floatValue(),plot.getCalculatedMinY().floatValue());
maxXY=new PointF(plot.getCalculatedMaxX().floatValue(),plot.getCalculatedMaxY().floatValue());
// plot.setClickable(true);
//NOTE about XYPlotZoomPan: when an OnTouchListener is set, zooming is disabled. Subclass to avoid it.
plot.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent me) {
//the begin of finding a point touched, then drawing two lines, and labeling the lines
touchX = me.getX();
touchY = me.getY();
widget = plot.getGraphWidget();
gridRect = widget.getGridRect();
if(gridRect.contains(touchX, touchY)){ //Check the touch event is in the grid
XYSeries xyData = plot.getSeriesSet().iterator().next();
long targetValX = Math.round(widget.getXVal(touchX));
System.out.println("Touched at " touchX ", " touchY ". Target val X: " targetValX);
if(plot.getSeriesSet().size() > 1){
System.out.println("More than one series in plot. Using only the first one");
}
for(int i = 0; i < xyData.size(); i){
long currValX = xyData.getX(i).longValue();
long currValY = xyData.getY(i).longValue();
//Calculate the range value of the closest domain value (assumes xyData is sorted in ascending X order)
if(currValX >= targetValX){
long currDiff = currValX - targetValX;
if(prevValX != null amp;amp; (targetValX - prevValX) < currDiff){
targetValY = xyData.getY(i-1).longValue();
}else{
targetValY = currValY;
}
break;
}
prevValX = currValX;
}
if(targetValY != null){
long maxValY = plot.getCalculatedMaxY().longValue();
long minValY = plot.getCalculatedMinY().longValue();
System.out.println("Target Y Value" targetValY);
float pixelPosY = gridRect.top ValPixConverter.valToPix((double)targetValY, (double)minValY, (double)maxValY, (float)gridRect.height(), true);
System.out.println("Pixel Pos Y: " pixelPosY);
Number numberForDaily = series2Numbers[ (int)targetValX];
widget.setDomainCursorPosition(touchX);
System.out.println("Touch X: " touchX);
plot.getGraphWidget().setSize(new SizeMetrics(
0, SizeLayoutType.FILL,
0, SizeLayoutType.FILL)
);
Paint paintForText = new Paint();
paintForText.setColor(Color.BLACK);
Paint paintForTextBackroud = new Paint();
paintForTextBackroud.setColor(Color.WHITE);
widget.setCursorLabelPaint(paintForText);
widget.setCursorLabelBackgroundPaint(paintForTextBackroud);
widget.getDomainLabelPaint().setTextSize(20);
widget.getRangeLabelPaint().setTextSize(20);
widget.getCursorLabelPaint().setTextSize(25);
System.out.println("Cursor is at = " targetValX " " targetValY);
getTheStartDate();
Calendar cal = new GregorianCalendar(year, month 1, day);
Integer theNumberOfTheStartDay = cal.get(GregorianCalendar.DAY_OF_YEAR);
//the offset
Integer addingTheDates = (theNumberOfTheStartDay (int)targetValX);
//convert number to a date which is readable
GregorianCalendar gcDate = new GregorianCalendar();
gcDate.set(GregorianCalendar.DAY_OF_YEAR, addingTheDates);
//if the day of the month is less than 10
//add a zero to the front of it so that the string can be ordered
if(gcDate.get(GregorianCalendar.DAY_OF_MONTH)<10){
StringBuilder sb = new StringBuilder();
sb.append("0");
sb.append(gcDate.get(GregorianCalendar.DAY_OF_MONTH));
fixZeroInDate = sb.toString();
}else{
fixZeroInDate= String.valueOf(gcDate.get(GregorianCalendar.DAY_OF_MONTH));
}
String stringOfFinalCycleDate=
(gcDate.get((GregorianCalendar.MONTH))) "/"
fixZeroInDate "/"
gcDate.get(GregorianCalendar.YEAR);
//UPDATING THE TEXTVIEWS BASED ON BUTTON TAP
cycleDate.setText(stringOfFinalCycleDate); //cycle date
cycleDay.setText(Long.toString(targetValX)); //cycle day
cycleDailyUsage.setText( numberForDaily.toString());//usage of single cycle day
System.out.println("Start time now");
//do math to get the running total of usage
findtheUsageSum(stringOfFinalCycleDate);
DecimalFormat df = new DecimalFormat("#0.00");
cycleOverallUsage.setText(String.valueOf(df.format(usageSumOnClick))); //overall usage by the cycle day
System.out.println("How much time has passed?");
}else{
System.out.println("Couldn't find the closest range to the selected domain coordinate");
}
plot.invalidate();
}else{
System.out.println("Touched outside the plot grid");
}
return false;
}
private void findtheUsageSum(String stringOfFinalCycleDate) {
ParseQuery<ParseObject> query3 = ParseQuery.getQuery("UsageCalculator");
query3.whereEqualTo("SiteID", ShowSatellitesActivity.IDchosen);
query3.addAscendingOrder("SiteID");
query3.setLimit(10000);
query3.whereLessThanOrEqualTo("usageDate", stringOfFinalCycleDate);
query3.selectKeys(Arrays.asList("dataUsedString", "usageDate"));
List<ParseObject> results1 = null;
try {
results1 = query3.find();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
usageSumOnClick = 0;
System.out.println("query3 size: " results1.size());
for (ParseObject data : results1) {
// looping for all the dates and usage
System.out.println("data used: " data.getString("dataUsedString"));
System.out.println("on date: " data.getString("usageDate"));
usageSumOnClick = usageSumOnClick Double.parseDouble(data.getString("dataUsedString"));
} //ends for loop
} //ends find the usage function
private void getTheStartDate() {
final Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = 1;
startDate = (month 1) "-" day "-" year;
}
});
}
Комментарии:
1. Что происходит / не происходит?
onProgressUpdate()
Даже вызывается? И вам действительно нужно очистить этот код, чтобы он был более читабельным2. Вызывается onProgressUpdateIs(), он просто не обновляет диалоговое окно.
Ответ №1:
Переопределите onProgressUpdate
метод, который предоставляет вам AsyncTask, не создавайте свой собственный.
Кроме того, не называйте onProgressUpdate
себя! Это метод обратного вызова, который используется системой для обеспечения обратного вызова вашего потока пользовательского интерфейса. Если вы вызовете его напрямую, код будет выполняться внутри фонового потока, где вы не сможете обновить пользовательский интерфейс. Вместо этого используйте publishProgress
.
Редактировать: чтобы иметь возможность передавать правильное значение publishProgress
, вам также необходимо указать общий тип при расширении AsyncTask (второй общий тип — это тип для выполнения).
Попробуйте сделать это так:
private static class MyAsync extends AsyncTask <Void, Integer, String> {
....
@Override
protected void onProgressUpdate(Integer... progress) {
alertDialog.setMessage("The graphs are loading...n" progress[0] "% Completed");
}
@Override
protected String doInBackground(Void... params) {
incrementor = 0;
for ( int i = 0; i<day; i ){
publishProgress(getThePercent);
....
Комментарии:
1. Спасибо, но у меня возникла проблема, из-за которой я ничего не могу передать в свою функцию publishProgress(). Знаете ли вы, как я могу разрешить publishProgress() принимать аргумент?
2. Изменить
extends AsyncTask <Void, Void, String>
наextends AsyncTask <Void, Integer, String>
3. Изменение того, что расширяет моя AsyncTask, помогло мне добавить аргумент в ‘onProgressUpdate (), так ЧТО СПАСИБО!!! Теперь у меня возникли проблемы, когда ‘onProgressUpdate ()’ вызывается / загружается после того, как все мои диаграммы уже загружены (что делает его бесполезным, потому что диалоговое окно предупреждения исчезает после загрузки диаграмм и никогда не попадает в мое диалоговое окно предупреждения). Есть ли какой-либо способ корректного обновления диалогового окна вовремя??? Спасибо!
4. Я пытался использовать таймер ожидания, но мне все еще не повезло. 🙁
5. Вы что-то делаете в потоке пользовательского интерфейса во время выполнения этой задачи?