Search for network printer NetworkOnMainThreadException [duplicate] - android

This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 8 years ago.
I get a android.os.NetworkOnMainThreadException when I run this code the jar is provide by the printer manufacture. The error come right at the StarIOPort.searchPrinter. I don't get the error running the demo code provide from the manufacture.
I'm trying to see if there is any network printers available on the local network.
private void PortDiscovery(String interfaceName)
{
final EditText editPortName;
ArrayList<String> arrayPortName;
List<PortInfo> BTPortList;
List<PortInfo> TCPPortList;
final ArrayList<PortInfo> arrayDiscovery;
try {
if (true == interfaceName.equals("BT")) {
BTPortList = StarIOPort.searchPrinter("BT:");
for (PortInfo portInfo : BTPortList) {
arrayDiscovery.add(portInfo);
}
}
if (true == interfaceName.equals("LAN")) {
TCPPortList = StarIOPort.searchPrinter("TCP:");
for (PortInfo portInfo : TCPPortList) {
arrayDiscovery.add(portInfo);
}
}
arrayPortName = new ArrayList<String>();
for(PortInfo discovery : arrayDiscovery) {
String portName;
portName = discovery.getPortName();
if(discovery.getMacAddress().equals("") == false) {
portName += "\n - " + discovery.getMacAddress();
if(discovery.getModelName().equals("") == false) {
portName += "\n - " + discovery.getModelName();
}
}
arrayPortName.add(portName);
}
} catch (StarIOPortException e) {
e.printStackTrace();
}
editPortName = new EditText(this);
new AlertDialog.Builder(this).setTitle("Please Input Port Name").setView(editPortName).setPositiveButton("OK", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int button){
EditText portNameField = (EditText)findViewById(R.id.printerName);
portNameField.setText(editPortName.getText());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int button) {
}
})
.setItems(arrayPortName.toArray(new String[0]), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int select) {
EditText portNameField = (EditText)findViewById(R.id.printerName);portNameField.setText(arrayDiscovery.get(select).getPortName());
}
})
.show();
}

You're getting the NetworkOnMainThreadException because the Android OS does not allow heavy processes (like network related operations) to run on the main thread (also called the UI Thread sometimes) because those operations/process may take a lot of resources and time to operate, and therefore, the application may lag.
A solution is to put your process in an executable thread and instantiate that thread in your onCreate() or where ever you need it, for example, on an onClickListener();. Do is like so:
private class Print extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("Hi", "Print Commencing");
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Printing...");
String message= "Printing";
SpannableString ss2 = new SpannableString(message);
ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);
ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0);
pDialog.setMessage(ss2);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
Log.d("Hi", "Printing");
//Toast.makeText(getApplicationContext(), "Printing.", Toast.LENGTH_LONG).show();
//insert your code here
return "Executed!";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Toast.makeText(getApplicationContext(), "Done printing.", Toast.LENGTH_LONG).show();
Log.d("Hi", "Done Printing.");
pDialog.dismiss();
}
}
and call it from a function like so:
new Print().execute("")
In the onPreExecute(), I initialize a progressDialog that is not cancellable to guarantee that your process ends properly. You should insert your code in the doInBackground(); part.

Related

How to do a progress bar to show progress download of a big file with AndroidAnnotations?

I have an Android App and I want to download a big file.
REST API implementation is made with AndroidAnnotations. I need to show a progressbar with the download of a big file using this REST Client (made by AndroidAnnotations).
How I to do that?
Regards
Hello Its to late for answering this question but this will be helpful who are still finding ans with Android-annotation
You can check your image progress by little bit manipulation of code and here is what i have created my
Custom converter Class:-
public class CustomConverter extends FormHttpMessageConverter {
OnProgressListener mOnProgressListener;
public CustomConverter() {
super();
List<HttpMessageConverter<?>> partConverters = new ArrayList<HttpMessageConverter<?>>();
partConverters.add(new ByteArrayHttpMessageConverter());
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
stringHttpMessageConverter.setWriteAcceptCharset(false);
partConverters.add(stringHttpMessageConverter);
partConverters.add(new ProgressResourceHttpMessageConverter());
setPartConverters(partConverters);
}
// public ProgressFormHttpMessageConverter setOnProgressListener(OnProgressListener listener) {
// mOnProgressListener = listener;
// return this;
// }
class ProgressResourceHttpMessageConverter extends ResourceHttpMessageConverter {
#Override
protected void writeInternal(Resource resource, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
InputStream inputStream = resource.getInputStream();
OutputStream outputStream = outputMessage.getBody();
byte[] buffer = new byte[2048];
long contentLength = resource.contentLength();
int byteCount = 0;
int bytesRead = -1;
Log.d("<3 <3 <3", "called");
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
byteCount += bytesRead;
Log.d("<3 <3 <3 ** ", "progress" + String.valueOf((byteCount * 100) / contentLength));
if(mOnProgressListener != null) {
mOnProgressListener.onProgress(resource, byteCount, (int) contentLength);
}
}
outputStream.flush();
}
}
public interface OnProgressListener {
void onProgress(Resource resource, int downloaded, int downloadSize);
}
}
--> you can check your progress with log :)
Code Usage
-> Your rest class will be as follow:-
#Rest(rootUrl = CommonUtils.BASE_URL, converters = {ByteArrayHttpMessageConverter.class,
CustomConverter.class, StringHttpMessageConverter.class})
public interface CustomRest extends RestClientErrorHandling {
#Post(pUrlSignUp)
String _SignUp(MultiValueMap<String, Object> multiValueMap);
}
Of course, you will have to use AsyncTask for downloading purpose:
You can use its methods onPreExecute and onPostExecute for showing and dismissing the ProgressDialog respectively.
Example:
public class DownloadTask extends AsyncTask<String, Integer, String>
{
ProgressDialog pDialog;
Activity activity; //pass your activity reference while initialize this.
public DownloadTask (Activity activity){
this.activity = activity;
}
#Override
protected void onPreExecute()
{
pDialog = new ProgressDialog(activity);
pDialog.setMessage("Downloading file...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
//download file's code here
}
#Override
protected void onPostExecute(String result)
{
pDialog.dismiss();
}
}
Hope this helps.
> use AsyncTask method "on progressupdate " to show progress
public class download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private Button startBtn;
private ProgressDialog mProgressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startBtn = (Button)findViewById(R.id.startBtn);
startBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
startDownload();
}
});
}
private void startDownload() {
String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
new DownloadFileAsync().execute(url);
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/some_photo_from_gdansk_poland.jpg");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
}
With AndroidAnnotations, you can use background threads and publishing progress easily:
#EActivity
public class MyActivity extends Activity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle)
doSomeStuffInBackground();
}
#Background
void doSomeStuffInBackground() { // will run on a background thread
publishProgress(0);
// Do some stuff
publishProgress(10);
// Do some stuff
publishProgress(100);
}
#UiThread
void publishProgress(int progress) { // will run on the UI thread
// Update progress views
}
}
Now you can only have to figure out how you can get progress events. This answer can give a great inspiration. Unfortunetaly AFAIK there is no built-in callback for that in Spring Android Rest Template.
I was looking to solve this same problem, its being two months now. Finally found a good example, I cant believe everybody copy paste the same in AndroidAnnotations docs, if that were enough, we wouldnt be here seeking for help.
Here is the link where you can see the example
I made some modifications my self, for the moment its working with some toasts, but I hope to comeback with an actual loading animation to share:
/*This background handles my main thread in UI and the progress publish*/
#Background
void thisGETJSON() {
publishProgress(0);
publishProgress(50);
publishProgress(100);
showJSONInUI();
}
/*Here the progress is published and the main UI thread is also called*/
#UiThread
void publishProgress(int progress) {
if (progress == 0) {
Toast toast = Toast.makeText(getApplicationContext(), "Just a sec please", Toast.LENGTH_SHORT);
toast.show();
} else if (progress == 50) {
Toast toast = Toast.makeText(getApplicationContext(), "Loading", Toast.LENGTH_SHORT);
toast.show();
} else if (progress == 100) {
Toast toast = Toast.makeText(getApplicationContext(), "Thanks for waiting", Toast.LENGTH_SHORT);
toast.show();
}
/*This is the main UI thread here I do cool stuff with the JSON objects*/
#UiThread
Void showJSONInUI(); {
//Here I do something with the objects in the JSON
}

Android AsyncTask Dialog fast close

My code:
private class selectBookInAutor extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
arr_book_title.clear();
arr_book_href.clear();
mProgressDialog = new ProgressDialog(_context);
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected String doInBackground(String... params) {
Document doc = null;
StringBuilder sb = new StringBuilder();
try {
doc = Jsoup.connect(params[0]).userAgent("Mozilla").get();
Elements links = doc.select("li>a");
for (Element link : links) {
sb.append(link.text());
arr_book_title.add(link.text());
arr_book_href.add(Jsoup.clean(link.attr("abs:href"), Whitelist.basic()));
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
#Override
protected void onPostExecute(String result) {
if (result != ""){
final CharSequence[] items = arr_book_title.toArray(new CharSequence[arr_book_title.size()]);
final ArrayList seletedItems = new ArrayList();
AlertDialog.Builder builder = new AlertDialog.Builder(_context);
builder.setTitle("Select The Difficulty Level");
builder.setMultiChoiceItems(items, null, new DialogInterface.OnMultiChoiceClickListener() {
#Override
public void onClick(DialogInterface dialog, int indexSelected, boolean isChecked) {
if (isChecked) {
seletedItems.add(indexSelected);
}else if(seletedItems.contains(indexSelected)){
seletedItems.remove(Integer.valueOf(indexSelected));
}
}
}).setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
for (Object s : seletedItems){
String[] separated = selGroupParam.split(";");
String _idautor = separated[0].toString();
long id_book = db.insertBOOK(_idautor, arr_book_href.get(Integer.valueOf(s.toString())).toString(), "", arr_book_title.get(Integer.valueOf(s.toString())).toString());
new **saveBookInAutor().execute(arr_book_href.get(Integer.valueOf(s.toString())).toString(), _idautor, String.valueOf(id_book));**
}
refreshList();
}
}).setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
}
}).create().show();
}else{
Toast.makeText(_context, "Error", Toast.LENGTH_SHORT).show();
}
mProgressDialog.dismiss();
}
}
private class saveBookInAutor extends AsyncTask<String, Void, String> {
String _idautor, _idbook;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog2 = new ProgressDialog(_context);
mProgressDialog2.setMessage("Save to file");
mProgressDialog2.setIndeterminate(false);
mProgressDialog2.show();
}
#Override
protected String doInBackground(String... params) {
Document doc = null;
String _html = "";
_idautor = params[1];
_idbook = params[2];
try {
doc = Jsoup.connect(params[0]).userAgent("Mozilla").get();
_html = doc.select("dd").outerHtml();
} catch (IOException e) {
e.printStackTrace();
}
return Jsoup.clean(_html, Whitelist.basic());
}
#Override
protected void onPostExecute(String result) {
if (result != ""){
Toast.makeText(_context, "Save file", Toast.LENGTH_SHORT).show();
String html = "<html lang='ru'><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/></head><body>"+result+"</body></html>";
//String html = result;
**savePageToFile(_idautor + "_" + String.valueOf(_idbook), html);**
}else{
Toast.makeText(_context, "Error", Toast.LENGTH_SHORT).show();
}
mProgressDialog2.dismiss();
}
}
public void refreshList() {
Intent intent = new Intent(_context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
_context.startActivity(intent);
}
public void savePageToFile(String filename, String html) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(_context.openFileOutput(filename, Context.MODE_PRIVATE));
outputStreamWriter.write(html);
outputStreamWriter.close();
}
catch (IOException e) {
//Log.e("Exception", "File write failed: " + e.toString());
}
}
When you select a page and clicking "Ok" ProgressDialog mProgressDialog2 opens and displays just a 1 second. Because of this, I do not see the download Page or not.
How to make mProgressDialog2 displayed all the while to save the page as a file?
Thank you!
UPD
What i want is :
Start mProgressDialog.
After downloading the page disappears and AlertDialog comes with the question what to choose.
After choosing, mProgressDialog2 should be displayed as long as it downloads and saves the file in the webpage.
However mProgressDialog2 disappears in 1 second, and process of saving the file goes on in silence.
In your onPostExecute method, you unconditionally call
mProgressDialog2.dismiss();
This is closing the dialog immediately after it is displayed. That call should be moved to the handler code for each of the buttons. (i.e.the onClick method for the positive and negative buttons)
in onPostExecute(), compare Strings like
if(!result.equals(""))
and try once.
use equals() method for String comparisons.

Cancel asynctask download on backbutton press

This is my download class in which I used Asynctask.Everything works fine, when the file is downloaded fully,it shows 'file downloaded' and on 'ok' press goes back to previous activity.Now I wanted to cancel the asynctask(pls not that 'cancel asynctask' and not only the 'loading' dialogue)on back button press and go back to previous activity.How to do that?someone please help.Thanks in advance
public class Download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.down);
startDownload();
}
private void startDownload() {
String url = data.proj;
new DownloadFileAsync().execute(url);
}
private void showMsg() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Document is downloaded")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
//do things
Download.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
String fname;
fname = data.proj.substring( data.proj.lastIndexOf('/')+1, data.proj.length() );
InputStream input = new BufferedInputStream(url.openStream());
String path=Environment.getExternalStorageDirectory()
.toString() + File.separator;
OutputStream output = new FileOutputStream(path+fname);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
showMsg();
}
}}
Really old question, but it seems many people still face an issue in cancelling AsyncTasks. So, here goes...
You will need a field in your AsyncTask class (DownloadFileAsync) to store the View which is being used to cancel the task (a ProgressDialog here).
For ProgressDialog, when creating the dialog, pass true to setCancelable()
mProgressDialog.setCancelable(true);
To pass the view, change the call to the Task as follows:
new DownloadFileAsync(mProgressDialog).execute(url);
and inside our AsyncTask class, create a constructor which saves this value to a field and register an OnCancelListener to call cancel method of AsyncTask:
ProgressDialog mProgressDialog;
DownloadFileAsync(ProgressDialog progressDialog) {
mProgressDialog = progressDialog;
mprogressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
cancel(true);
}
});
}
In your while loop in doInBackground, add the following code inside the loop:
if (isCancelled()) {
outputStream.flush();
outputStream.close();
inputStream.close();
return null;
}
This way we are checking whether the task was cancelled, every once in a while, and if yes, we close open streams and stop running the task with return (return will be of type given for result of Task). Next, in onCancelled
#Override
protected void onCancelled (Integer fileSize) {
super.onCancelled(fileSize);
Log.d("TASK TAG", "Cancelled.");
//anything else you want to do after the task was cancelled, maybe delete the incomplete download.
}
this is how i did
public class downloadAllFeeds extends AsyncTask<Void, Void, Void>
implements OnCancelListener{
protected void onPreExecute() {
pDialog2.setCancelable(true);
pDialog2.setOnCancelListener(this);
}
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
downloadAllFeeds.this.cancel(true);
Log.d("on click cancel true","true");
}
#Override
protected Void doInBackground(Void... params) {
if(isCancelled()==true){
//cancel true stop async
Log.d("cancel true","true");
}else{
//perform your task
}
}
this worked for me, i know this is very old question but it didnt have a answer so i thought i should share what i just now could implement :)

progress dialog is not displaying in async task when asynctask is called from separate class

I have posted a question
Progress Dialog is not displaying while getting data from separate thread class
but I haven't got the appropriate answers. I have already used async task to display progress dialog but it is not displaying.
here is the sample code
public class JsonData extends AsyncTask<String, String, String> {
private ProgressDialog mProgressDialog;
Context context;
public JsonData(Context context)
{
this.context=context;
mProgressDialog = new ProgressDialog(context);
mProgressDialog.setMessage("Loading Please Wait.");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.show();
}
#Override
protected String doInBackground(String... aurl) {
String results="";
try {
int k=0;
URL url1;
url1 = new URL(aurl[0]);
InputStream input=url1.openStream();
BufferedInputStream bis=new BufferedInputStream(input);
ByteArrayBuffer baf=new ByteArrayBuffer(1000);
while((k=bis.read())!=-1)
{
baf.append((byte)k);
}
results=new String(baf.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
return results;
}
#Override
protected void onPostExecute(String jsondata) {
mProgressDialog.dismiss();
}
}
Here is the method in which I have called the async task
private void getRecordsByCount(final String data) {
try {
int color=Color.BLACK;
tableLayoutGrid.removeAllViews();
final String[] details = data.split("_");
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
String formattedDate = df.format(new Date());
String url = ipaddress + "/GrantLeavesList?Companyid=" + user_info.get("CompanyId") + "&divisionid=" + details[3] + "&userid=" + user_info.get("userid") + "&roleid="
+ user_info.get("RoleId") + "&Employeeid=" + user_info.get("EmployeeId") + "&leavetypeid=" + staticDetails.get(details[0]) + "&strStatus=" + staticDetails.get(details[1])
+ "&type=" + staticDetails.get(details[2]) + "&Date=" + formattedDate;
String url2=ipaddress + "/GrantLeavesChildList?Companyid=" + user_info.get("CompanyId") + "&divisionid=" + details[3] + "&userid=" + user_info.get("userid") + "&roleid="
+ user_info.get("RoleId") + "&Employeeid=" + user_info.get("EmployeeId") + "&leavetypeid=" + staticDetails.get(details[0]) + "&strStatus=" + staticDetails.get(details[1])
+ "&type=" + staticDetails.get(details[2]) + "&Date=" + formattedDate;
JsonData jdata=new JsonData(context);
jdata.execute(url,null,null);
String jsonString=jdata.get();
JSONObject obj=new JSONObject(jsonString);
JsonData jdataChild=new JsonData(context);
jdataChild.execute(url2,null,null);
String jsonChildString=jdataChild.get();
JSONObject objchild=new JSONObject(jsonChildString);
btnGrantSubmit.setVisibility(View.GONE);
if (obj != null) {
leaveforwardcounts = obj.getJSONArray("Table1");
leaveforwardchildcounts=objchild.getJSONArray("Table11");
ScrollView scrollGrid = new ScrollView(this);
TableRow datarow = new TableRow(this);
datarow.setWeightSum(100);
TableLayout table = new TableLayout(this);
for (int i = 0; i < leaveforwardcounts.length(); i++) {
btnGrantSubmit.setVisibility(View.VISIBLE);
JSONObject record = leaveforwardcounts.getJSONObject(i);
String applicantname = record.getString("Applicant");
String toDate = record.getString("ToDate");
String noofdays = record.getString("NumberOfDays");
String LOP = record.getString("LOP");
if(LOP!=null && LOP.trim().length()!=0)
{
color=Color.RED;
}
final int id = i;
final Button gridbutton = new Button(this);
gridbutton.setText(status);
gridbutton.setTextColor(Color.BLACK);
gridbutton.setBackgroundResource(R.drawable.grdbutton_30x30);
gridbutton.setGravity(Gravity.CENTER);
gridbutton.setPadding(2, 0, 2, 0);
gridbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
changeRadioButtonState(gridbutton, id, data);
}
});
gridbutton.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
setSelection(gridbutton);
return true;
}
});
TextView tvApplicantName = new TextView(this);
TextView tvToDate = new TextView(this);
TextView tvNoOfDays = new TextView(this);
TextView empty = new TextView(this);
TextView empty2 = new TextView(this);
if (applicantname.trim().length() >= 18) {
applicantname = applicantname.substring(0, 18);
}
tvApplicantName.setText(applicantname);
tvApplicantName.setTypeface(font2);
tvApplicantName.setWidth(70);
tvApplicantName.setTextColor(color);
tvApplicantName.setPadding(5, 0, 0, 0);
tvToDate.setText(toDate);
tvToDate.setTypeface(font2);
tvNoOfDays.setText(noofdays);
tvNoOfDays.setTypeface(font2);
tvNoOfDays.setGravity(Gravity.RIGHT);
Button ivDetails = new Button(this);
ivDetails.setText(" ");
ivDetails.setPadding(2, 0, 2, 0);
ivDetails.setBackgroundResource(R.drawable.detailsbutton_30x30);
ivDetails.setGravity(Gravity.CENTER);
ivDetails.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
leaveDetails = new PopupWindow(showLeaveDetails(id, leaveforwardcounts,data,leaveforwardchildcounts), (int) (width * 0.8), height / 2, true);
leaveDetails.showAtLocation(mainlayout, Gravity.CENTER, 0, 0);
}
});
TableRow row = new TableRow(this);
row.setPadding(0, 3, 0, 3);
row.setWeightSum(100);
row.addView(tvApplicantName, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 55));
row.addView(tvNoOfDays, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 5));
row.addView(empty2, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 20));
row.addView(ivDetails, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 5));
row.addView(empty, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 5));
row.addView(gridbutton, new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 5));
table.addView(row);
}
scrollGrid.addView(table);
datarow.addView(scrollGrid, new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, 100));
tableLayoutGrid.addView(datarow);
}
} catch (Exception e) {
e.printStackTrace();
}
}
I need to build page based on the data from Service. in my app there are about 20-30 services.. if i use async task as inner class it works well and good ...but How can reuse my code...
you dont need to start a background method for postExecute. as #baske wrote, you have problem with .get() - that is blocking your thread even if your are using AsyncTask.
try someting related to the linked question, so only add your YourActivityClass as a param to the construdtor of JsonData
public JsonData(YourActivityClass activity)
{
this.activity=activity;
mProgressDialog = new ProgressDialog(activity);
}
protected void onPostExecute(String jsondata) {
if (mProgressDialog != null || mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
if(jsondata!=null) {
activity.yourcallback(jsondata)
}
}
And define the yourcallback() in YourActivityClass
private void yourcallback(String data) {
jsonRecordsData=data;
showRecordsFromJson();
}
user, I think you need to understand better what the reasons are for using an AsyncTask and what the uses are of the callback/hook methods it provides.
Starting with the reason: if you have a long-running task, you cannot run this on the main thread (also called UI thread) because your app will eventually show ANR errors. Now if your long-running task would not need to show output on the screen (when it is done, progress reports, etc) you can very well put it in a worker thread and let it run by itself (possibly even delegating it to a Service to guarantee run-to-completion, but that is another story). However, a lot of times this isn't the case and you want to update your UI based on the outcome/progress of your long-running task. To do this you would have to somehow branch off a thread and do the work there, but, since you can only manipulate the UI from the main thread, you would have to post back the result on the main thread when you are done.
This is where we move to the AsyncTask and its hook methods. An AsyncTask is actually just a Utility class that helps you do exactly what is explained above: put your work on a separate thread and get a callback on your main thread when it is done (and the result is available). Checking the documentation you will find:
onPreExecute(): guaranteed to run on the main thread. Allows you to do stuff (like show a progress dialog) BEFORE the work starts.
doInBackground(): guaranteed to run on a background thread. Do you long running stuff here.
onPostExecute(): guaranteed to run on the main thread AFTER your doInBackground() has finished. The result of your task is now available and you can do stuff with it (like put it on the screen).
Getting back to your suggestions about your .get() method having a problem: since you are calling .execute() on your AsyncTask and .get()-ing the result immediately thereafter, chances are that the background job has not yet finished. Instead you should be doing whatever you wanted to do, starting at the .get() in the AsyncTask's onPostExecute. So if your task downloads an image and you want to show a "downloading" message to the user while it is running, you should do the following:
//pseudo code
void exampleButtonClicked() {
new AsyncImageDownloader.execute();
}
class AsyncImageDownloader extends AsyncTask {
onPreExecute() {
show "downloading";
}
doInBackground() {
downloadImg();
}
onPostExecute() {
hide "downloading";
put downloaded img on ImageView;
}
}
//end of pseudo code
Hope this helps.. Not going to code out your answer, because then you would have learned nothing ;-)
Cheers!
You can do UI operations only from an UI thread. Try running it on an UI thread.
runOnUiThread(new Runnable() {
public void run() {
mProgressDialog.show();
}
});
You can do on override methods onPreExecute() and implement for this code,
#Override
protected void onPreExecute() {
super.onPreExecute();
ProgressDialog mProgressDialog = ProgressDialog.show(ActivityName.this, "Wait", "Loading....");
}
and onPostExecute() method implement and dismiss the dialog,
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (mProgressDialog != null || mProgressDialog.isShowing())
mProgressDialog.dismiss();
}
Try the following:
#Override
protected void onPreExecute()
{
mProgressDialog =ProgressDialog.show(GmailInbox.this, "", "Please Wait",true,false);
super.onPreExecute();
}

how to detect whether the function has run finished?

webservice.UpdateAllNews();
This function is downloading data from online database to local database.
What i want is i want to launch next activity after detect the function has downloaded finish all the data.
P/S the data is large
This is my current situation
webservice.UpdateAllNews();
int secondsDelayed = 17;
new Handler().postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(Main_Launcher.this,
Main_AllLatestNews.class));
finish();
}
}, secondsDelayed * 1000);
This is another class function
public void UpdateAllNews() {
try {
List<List_CategoryNews> newsCat = dbhelper.getAllNewsCategories();
for (List_CategoryNews nwCat : newsCat) {
int CatNewsID = nwCat.getCatID();
if (CatNewsID != 0) {
dbhelper.DeleteNews(CatNewsID);
GetNews(CatNewsID, datetemp1, datetemp2);
}
String log = " NewsCatID- " + nwCat.getCatID()
+ " category Name- " + nwCat.getNewCatName();
System.out.println(log);
}
} catch (Exception ex) {
AlertDialog.Builder b = new AlertDialog.Builder(mContext);
b.setMessage(ex.toString());
b.show();
}
}
This one is constant launch after 17 seconds, i want auto start activity after finish downloading data from online database instead of delay 17 seconds.
Any suggestion?
Maybe try to use AsyncTask:
private class YourTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... urls)
{
webservice.UpdateAllNews();
}
#Override
protected void onPostExecute(String result)
{
startActivity(new Intent(Main_Launcher.this,Main_AllLatestNews.class));
finish();
}
}
and how to run it:
YourTask task = new YourTask();
task.execute("...");
Why don't you use simple client-server methodology like Observer-Observable?
When the task is done the observable will call update function of the observer which will be your primary activity.

Categories

Resources