I'm pretty new to app development, but I have an issue I can't figure out.
I have a splash screen I am using to load various things that the app needs to function (config files, html from the internet) and the latter is giving me a huge problem. Here is the code
Document doc = null;
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splash);
//Fix loading data, dunno why this happens
try {
doc = new getHtml().get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
/* New Handler to start the Menu-Activity
* and close this Splash-Screen after some seconds.*/
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Utils.saveData(Splash.this, doc);
Intent mainIntent = new Intent(Splash.this, PocketFrameNavigation.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
public static class getHtml extends AsyncTask<Void, Void, Document> {
protected Document doInBackground(Void... args) {
try {
return Jsoup.connect(DROP_DATA_URL).get();
} catch(Exception e) {
return null;
}
}
protected void onPostExecute(Document html){
doc = html;
}
}
The code that's giving me an issue is the inside the try statement. It seems to freeze the main thread, no matter where I put it. Is there something I am doing terribly wrong? Thanks in advance for the help.
Also, the getHTML function works whenever there is not a post delayed handler involved. so i think it has something to do with that.
I think that will be work:
Document doc = null;
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splash);
new GetHTMLContent().excute();
}
private static class GetHTMLContent extends AsyncTask<Void, Void, Document> {
protected Document doInBackground(Void... args) {
try {
return Jsoup.connect(DROP_DATA_URL).get();
} catch(Exception e) {
return null;
}
}
protected void onPostExecute(Document html){
doc = html;
Utils.saveData(Splash.this, doc);
goToMainActivity();
}
}
private void goToMainActivity(){
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this, PocketFrameNavigation.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
}
Related
Right now I'm simulating the showing of a ProgressDialog for an event that is expected to take several seconds.
I'm doing it this way:
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage(getString(R.string.calendar_load));
progressDialog.setCancelable(false);
progressDialog.show();
Thread t=new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run() {
progressDialog.cancel();
progressDialog.hide();
But even though I've checked in debug that the progressDialog.cancel() and progressDialog.hide() execute the dialog just keeps on showing apparently in an indefinite way.
What could be causing such behavior?
PROBLEM SOLVED: Thanks to everyone who has answered/commented, it looks like an emulator bug (indeed it has also worked some times on emulator).
Call progressDialog.dismiss();
Could you try this snippet?
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try {
while (progressDialog.getProgress() <= progressDialog.getMax()) {
Thread.sleep(100);
handle.sendMessage(handle.obtainMessage());
if (progressDialog.getProgress() == progressDialog.getMax()) {
progressDialog.dismiss();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
Handler handle = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.incrementProgressBy(1);
}
};
public class ConnectionTest extends AsyncTask<Void, Void, Void> {
String connection;
String loginFormUrl = "https://intranet.tam.ch/";
#Override
protected Void doInBackground(Void... voids) {
try{
Connection.Response loginForm = Jsoup.connect(loginFormUrl).method(Connection.Method.GET)
.execute();
connection = loginForm.toString();
System.out.print(title);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
My Activity should just display the connection in a TextView. I have also tried making a Thread and running it in the new Thread but it also won't work.
Here is my Activity
public class Test extends AppCompatActivity {
TextView textView;
ConnectionTest connectionTest = new ConnectionTest();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
connectionTest.getWebsite();
textView = findViewById(R.id.sdweedew);
textView.setText(connectionTest.connection);
}
}
Change your activity code like this,
I've used a TextView to display the status of the connection.
public class MainActivity extends AppCompatActivity {
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
textView = findViewById(R.id.sdweedew);
new ConnectionTest().execute();
}
class ConnectionTest extends AsyncTask<Void, Void, String> {
String loginFormUrl = "https://intranet.tam.ch/";
#Override
protected String doInBackground(Void... voids) {
try {
Connection.Response loginForm = Jsoup.connect(loginFormUrl).method(Connection.Method.GET)
.execute();
return loginForm.statusMessage();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
if (textView != null) {
textView.setText(s);
}
super.onPostExecute(s);
}
}
}
And remember to add Internet permission in manifest file.
<uses-permission android:name="android.permission.INTERNET" />
please check this code
private void getWebsite() {
new Thread(new Runnable() {
#Override
public void run() {
final StringBuilder builder = new StringBuilder();
try {
Document doc = Jsoup.connect("https://intranet.tam.ch/").get();
String title = doc.title();
Elements links = doc.select("a[href]");
builder.append(title).append("\n");
for (Element link : links) {
builder.append("\n").append("Link : ").append(link.attr("href"))
.append("\n").append("Text : ").append(link.text());
}
} catch (IOException e) {
builder.append("Error : ").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(builder.toString());
}
});
}
}).start();
}
I am having a problem which is I think that I can't access th,e ListView from the asyncTask
Actually, I really don't know the real problem here
Let me show you what is happening
I have an activity which is executing AsyncTask and creates HttpURLConnection. Sometimes I get an exception (ProtocolException) because the stream un-expectedly ends.
So, I created a handler for this exception that calls a function or a method inside the class of the activity to display a message to the user
Here is a picture so you understand what is my project.
image
the problem here whenever the exception is thrown, the same function/method that I use to add the text to the listView is called, but after it called the listView disappear, but when I minimize the soft keyboard manually the everything becomes fine.
the structure of my class is
public class MainActivity extends AppCompatActivity
{
protected void onCreate(Bundle savedInstanceState)
{
addMessageToListView()//works fin here
}
protected void addMessage(String message, int userMessage, ListView listView) // the function
{
try
{
messages.add(new Message(message,userMessage));
MessagesAdapter messagesAdapter = new MessagesAdapter(messages, getBaseContext());
messagesAdapter.notifyDataSetChanged();
listView.setAdapter(messagesAdapter);
}
catch (Exception exception)
{
}
}
private class HttpPostAsyncTask extends AsyncTask<String, Void, String>
{
...
#Override
protected void onPostExecute(String result)
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
}
}
protected String doInBackground(String... params)
{
String result = "";
for (int i = 0; i <= 0; ++i)
{
result = this.invokePost(params[i], this.postData);
}
return result;
}
private String invokePost(String requestURL, HashMap<String, String> postDataParams)// called from doInBackground
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
addMessageToListView()//not orking here
}
}
}
}
I don't know how to explain more actually.
You can change Views only in mainthread of your app. The doInBackground doesn't run in mainthread of your app.
Solved by adding:
new Thread()
{
#Override
public void run()
{
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
addMessageToListView()//not orking here
}
});
super.run();
}
}.start();
Editing the previous code in my question:
public class MainActivity extends AppCompatActivity
{
protected void onCreate(Bundle savedInstanceState)
{
addMessageToListView()//works fin here
}
protected void addMessage(String message, int userMessage, ListView listView) // the function
{
try
{
messages.add(new Message(message,userMessage));
MessagesAdapter messagesAdapter = new MessagesAdapter(messages, getBaseContext());
messagesAdapter.notifyDataSetChanged();
listView.setAdapter(messagesAdapter);
}
catch (Exception exception)
{
}
}
private class HttpPostAsyncTask extends AsyncTask<String, Void, String>
{
...
#Override
protected void onPostExecute(String result)
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
}
}
protected String doInBackground(String... params)
{
String result = "";
for (int i = 0; i <= 0; ++i)
{
result = this.invokePost(params[i], this.postData);
}
return result;
}
private String invokePost(String requestURL, HashMap<String, String> postDataParams)// called from doInBackground
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
new Thread()
{
#Override
public void run()
{
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
addMessageToListView()//not orking here
}
});
super.run();
}
}.start();
}
}
}
}
I'm trying to show a ProgressDialog from an AsyncTask but is not showing... if I delete the 'dialog.dismiss()' of the PostExecute, this task works like a 'post()', it shows the Dialog in the end of the task. I'm getting crazy with this!
private static class Experimento extends AsyncTask<String, Void, String>
{
ProgressDialog dialog;
#Override
protected void onPreExecute()
{
super.onPreExecute();
dialog = new ProgressDialog(Config.getCurrent_Context());
dialog.setMessage("Cargando...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
protected String doInBackground(String... params)
{
try
{
Config.getCurrent_Context().runOnUiThread(new Runnable()
{
#Override
public void run()
{
try
{
//Work, work, work...
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result)
{
super.onPostExecute(result);
dialog.dismiss();
}
}
Now tried giving the Activity in the constructor but still not working...
private static ProgressDialog dialog;
public Experimento(Activity act)
{
Log.w("Experimento", "Experimento");
dialog = new ProgressDialog(act);
dialog.setMessage("Cargando...");
dialog.setCancelable(false);
dialog.show();
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
You should remove setIntermidiate(true);
Try this, it works for me:
Override
protected void onPreExecute()
{
dialog = new ProgressDialog(Config.getCurrent_Context());
dialog.setMessage("Cargando...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
protected String doInBackground(String... params)
{
String result = " ";
try
{
Config.getCurrent_Context().runOnUiThread(new Runnable()
{
#Override
public void run()
{
try
{
//Work, work, work...
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
return result;
}
protected void onPostExecute(String result)
{
dialog.dismiss();
}
This error is Showing often "The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread."
Getting the NewsList and other images and ads from API using JSON.
class LongOperation extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
}
protected String doInBackground(String... params) {
try {
AdSpotList.add(sched);
Image_view_List.add(sched);
NewsList.add(sched);
handler.sendEmptyMessage(1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String result) {
}
}
Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
if (NewsList.size() != 0) {
if (NewsList.size() <= 5) {
adapter = new CustomAdapter(getActivity(),
Image_view_List, NewsList, AdSpotList, res);
lv_daily_summary.setAdapter(adapter);
} else {
getActivity().runOnUiThread(new Runnable() {
public void run() {
lv_daily_summary.invalidateViews();
adapter.notifyDataSetChanged();
}
});
}
}
}
}
};
This complete page is on the Fragment.