how to use runOnUiThread for Update Adapter - android

following code, I try update Adapter. Code is properly done .But Mobile to goes Hong mode.After the loop ends. Data is displayed.
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
_adapter.notifyDataSetChanged();
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
_adapter.notifyDataSetChanged();
}
}
});
Update :
I changed my code like the following code.
Hong mode is still not resolved.How do I fix it?
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
_adapter.notifyDataSetChanged();
}
});
Update 2 :
public static Bitmap GetImageFromUrl(String url) {
URL urlForImage;
Bitmap imageNews=null;
try {
urlForImage = new URL(url);
URLConnection conn = urlForImage.openConnection();
imageNews= BitmapFactory.decodeStream(conn.getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageNews;
}
Update 3 :
again : I changed my code like the following code. Hong mode is still not resolved.
public class AsyncTaskReadImageNews extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("INDEX_ITEM", String.valueOf(currentIndex));
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
_adapter.notifyDataSetChanged();
}
}
}
This is all my code :
public class MainActivity extends Activity {
NewsAdapter _adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
boolean result=true;
int id = item.getItemId();
switch (id) {
case R.id.action_transfer_news:
SharedVar.setCurrentTask(Taskes.GET_TRANSFER_NEWS);
new JsoupCommands().ConnectToWebsite(MainActivity.this);
break;
case R.id.action_settings:
break;
default:
result=super.onOptionsItemSelected(item);
break;
}
return result;
}
public class JsoupCommands {
private Dialog _dialog;
private RatingBar _loadingStar;
public void ConnectToWebsite(Context context) {
_dialog = new Dialog(context);
_dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
_dialog.setContentView(R.layout.loading_layout);
_loadingStar=(RatingBar) _dialog.findViewById(R.id.loading_RatingBar);
Helpers.ConfigRatingLoader(_loadingStar);
new AsyncTaskJsoup().execute();
}
public class AsyncTaskJsoup extends AsyncTask<Void, Void, String>{
boolean _startThread;
Element _NewsRegion;
Elements _links;
List<News> _LisOfNews;
int _step=0;
#Override
protected String doInBackground(Void... listviews) {
String result=null;
Document doc;
try {
threadLoading.start();
SharedVar.clearNews();
doc = Jsoup.connect(Helpers.getCurrentTaskLink()).get();
_NewsRegion = doc.getElementById("content-post");
_links = _NewsRegion.select("article div[class=arch_body]");
_LisOfNews = new ArrayList<News>();
for (Element element : _links) {
Element textNewsElement = element.select("div[class=arch_content] a").first();
Element imageNewsElement = element.select("div[class=arch_img] a img").first();
String imageSrcNews = imageNewsElement.attr("src").trim().replace("../../../..", Helpers.GetCurrentSite());
String titleNews = textNewsElement.text().trim();
String linkNews = textNewsElement.attr("href").trim().replace("../../..", Helpers.GetCurrentSite()+"/persian");
String dateNews=textNewsElement.nextSibling().toString().trim();
News news = new News();
news.setIndex(_LisOfNews.size());
news.setTitle(titleNews);
news.setLink(linkNews);
news.setDate(dateNews);
news.setImageNewsAddress(imageSrcNews);
_LisOfNews.add(news);
}
SharedVar.setCurrentNews(_LisOfNews);
result="Success";
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
Thread threadLoading = new Thread()
{
#Override
public void run() {
try {
while(_startThread) {
Helpers.SetRatingLoad(_loadingStar, _step);
if(_step++==3){
_step=0;
}
Log.d("DELAY", String.valueOf(_step));
sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
#Override
protected void onPostExecute(String result) {
_startThread=false;
_dialog.dismiss();
FillNewsinListView();
new AsyncTaskReadImageNews().execute();
}
private void FillNewsinListView() {
List<News> news=SharedVar.getCurrentNews();
if(news!=null&&news.size()>0){
Log.d("FILL_NEWS", "YES");
_adapter = new NewsAdapter(MainActivity.this, R.layout.rows_news, SharedVar.getCurrentNews());
((ListView)findViewById(R.id.news_listView)).setAdapter(_adapter);
}else{
Log.d("FILL_NEWS", "NO");
}
}
#Override
protected void onPreExecute() {
_startThread=true;
_dialog.show();
}
}
public class AsyncTaskReadImageNews extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("INDEX_ITEM", String.valueOf(currentIndex));
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
_adapter.notifyDataSetChanged();
}
}
}
}

Your app hangs because you're doing the image downloading on the UI Thread. You'll need to do the image downloading off the UI thread.
What I'd suggest is to create an AsyncTask, add all the processing inside doInBackground() method and the _adapter.notifyDataSetChanged() inside onPostExecute() since this is the only thing that you need to call on the UI Thread.

change this:
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
_adapter.notifyDataSetChanged();
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
_adapter.notifyDataSetChanged();
}
}
});
to this:
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
_adapter.notifyDataSetChanged();
}
});
explanation : calling notifyDataSetChanged many times in a row, is a bad idea.
make your updates to the data, and then call it once!
your code was calling it twice for every news item.

Your are calling notifyDataSetChanged() in your for loop which is a bad practice and that to you are calling it twice. So remove notifyDataSetChanged() from your for loop. A better approach would be to move your code to an AsyncTask inside doInBackground() and then call notifyDataSetChanged() in your onPostexecute().

Related

How to add item from bottom to top after Pull refresh ListView?

This is my class for Print List-view in Android
public class ChatActivity extends FragmentActivity implements OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.act_chat);
listview = (PullToRefreshListView) findViewById(R.id.listView);
editMsg = (EditText) findViewById(R.id.txt_inputText);
mLastSeenTime = (TextView) findViewById(R.id.lastSeenDatetextview);
sendMsgBut = (ImageView) findViewById(R.id.btn_Send);
recciverImage = (ImageView) findViewById(R.id.recciverImage);
backbutton = (ImageView) findViewById(R.id.contact_btnMenu);
sendMsgBut.setOnClickListener(this);
recciverImage.setOnClickListener(this);
backbutton.setOnClickListener(this);
arrChatlist = dbHelper.fetchChatHistory(member_id, reccvierid);
chatList.addAll(arrChatlist);
chatAdapter = new ChatAdapter(this, chatList);
listview.setAdapter(chatAdapter);
listview.setSelection(listview.getAdapter().getCount() - 1);
dbHelper.updateIsRead(reccvierid);
#Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.btn_Send:
if (TextUtils.isEmpty(editMsg.getText().toString()))
return;
else {
mChatService.SendMessage(Integer.parseInt(member_id), Integer
.parseInt(reccvierid), editMsg.getText().toString());
Chat chat = new Chat();
chat.setMessage(editMsg.getText().toString());
chat.setRecieverID(reccvierid);
chat.setSenderID(member_id);
chatList.add(chat);
dbHelper.addMessage(chat);
chatAdapter.notifyDataSetChanged();
editMsg.setText("");
System.out.println("Messae : " + chat.getMessage());
listview.setSelection(listview.getAdapter().getCount() - 1);
}
break;
default:
break;
}
}
// ****************************** For Location Name *********|||||||
private class SyncStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getIntExtra(BroadcastNotifier.EXTENDED_DATA_STATUS,
BroadcastNotifier.STATE_ACTION_COMPLETE)) {
case BroadcastNotifier.STATE_ACTION_MESSAGE_RECEVED:
boolean isCurrentUser = false;
Chat chat = (Chat) intent
.getSerializableExtra(BroadcastNotifier.EXTENDED_CHAT_RECEIVED);
for (Datamodel model : HomeActivity.arrModel) {
if (("~" + model.getPhoneNumber()).equals(chat
.getSenderName())) {
chat.setSenderID(model.getId());
chat.setSenderName(model.getContactName());
}
if (chat.getConnectionId().equals(ConnectionId)) {
isCurrentUser = true;
}
}
if (isCurrentUser) {
dbHelper.addMessage(chat);
chatList.add(chat);
chatAdapter.notifyDataSetChanged();
listview.setSelection(listview.getAdapter().getCount() - 1);
} else {
mChatService.createNotification(chat);
}
break;
}
}
}
//-------- SigNal R Method------------------------\\\
public ChatEventHandler mChatHandler = new ChatEventHandler() {
String previousMessage = "";
#Override
public void UpdateMessage(String message, String sendername,
long senderId) {
if (previousMessage != message) {
System.out.println("new message: " + message + " sendername:"
+ sendername);
Chat chat = new Chat();
chat.setMessage(message);
chat.setRecieverID(member_id);
chat.setSenderID("" + senderId);
chat.setSenderName(sendername);
chat.setIsUnread(false);
dbHelper.addMessage(chat);
chatList.add(chat);
previousMessage = message;
listview.setSelection(listview.getAdapter().getCount() - 1);
}
runOnUiThread(new Runnable() {
#Override
public void run() {
chatAdapter.notifyDataSetChanged();
listview.setSelection(listview.getAdapter().getCount() - 1);
}
});
}
class loadmessge extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
chatAdapter.notifyDataSetChanged();
listview.onRefreshComplete();
super.onPostExecute(result);
}
}
}
This is my XML of listview:
<com.lociiapp.PullToRefreshListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:stackFromBottom="true"
android:transcriptMode="normal" >
I am able to display list-view in Android. Using chatadapter I have applied pull to refresh listview to load data 1 - 1 item in listview after refreshing but its working fine but I want to display that after refresh last item come in last in adapter and first item come in top adapter like tat way but I am unable to do that please see my screen you ll better understand what am trying to do please suggest how I will achieve.
.
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
chatAdapter.notifyDataSetChanged();
// loadPopupData(context, listView, emptyView,i);
listview.setSelection(listview.getAdapter().getCount() - 1);
listview.onRefreshComplete();
super.onPostExecute(result);
}
}
replace this code and Enjoy!!!
Append your chat messages at the end of your list, or implement getItem to return items reversed (length - position).
Looking at your code, I think the first option is the easiest:
public void addMessage(Chat chat) {
values.add(values.size()-1, chat);
this.notifyDataSetChanged();
}

Return value from AsyncTask without get() method

I'm trying to return value from my asynctask in DoInBackground, but calling get() method freezes my UI. How can I re-write my code to a callback method? :
public class GetUrlDataTask extends AsyncTask<String, Integer, String> {
String response;
HttpUtils util;
#Override
protected String doInBackground(String... params) {
try {
util = new HttpUtils(params[0]);
response = util.getContent();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
In my activity I get result as response = new GetUrlDataTask().execute("site").get;
You shouldn't use .get() if the Async task is going to take any decent amount of time (which it usually is).
Instead, you can either use a message/handler/service/etc, or you can simply use the onPostExecute(Result) method.
EDIT: New Code. Based on your description, it seems like you need to use an interface.
If you need to have Asynctask in another class, then an interface is probably your best option.
TestTask.java (your separate Asynctask):
import android.os.AsyncTask;
// Remember to change object type <> to what you need
public class TestTask extends AsyncTask<Object,Object,Object> {
public interface OnTaskCompleted{
void onTaskCompleted();
}
private OnTaskCompleted listener;
public TestTask(OnTaskCompleted listener){
this.listener = listener;
}
protected void onPostExecute(Object o){
// Call the interface method
if (listener != null)
listener.onTaskCompleted();
}
#Override
protected Object doInBackground(Object... params) {
// The sleep() is just to simulate activity and delay
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
MainActivity.java (or any other activity):
public class MainActivity extends Activity {
private boolean status = false;
private OnTaskCompleted listener = new OnTaskCompleted() {
public void onTaskCompleted() {
status = true;
Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(MainActivity.this, "Status: " + status, Toast.LENGTH_SHORT).show();
new TestTask(listener).execute("Testing");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I'm not a big fan of having AsycTask tasks in separate classes, especially if you need to use the response. It makes interacting with the response and local variables overly difficult considering how easy it is when implemented as an inner class.
I'm guessing you put it in its own class so you can reuse it. I would consider keeping the AsycTask as an inner class and calling outside reusable objects/methods in doInBackground(). This will keep the code DRY and allow your activity to do what it needs with the response.
public class MyActivity extends Activity {
TextView textview;
//...
private class GetUrlTask extends AsyncTask<String, Integer, String> {
protected String doInBackground(String... params) {
return new GetHttpResponse().get(params[0]);
}
protected void onPostExecute(String response) {
//Do UI updates...
textview.setText(response);
}
}
}
public class GetHttpResponse {
public String get(String url) {
try {
util = new HttpUtils(url);
response = util.getContent();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response;
}
}
You could do something like this:
public class MyActivity extends Activity
{
public void someMethod()
{
// Here you could put up a ProgressDialog
GetUrlDataTask myTask = new GetUrlDataTask();
myTask.execute();
}
public class GetUrlDataTask extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... params)
{
String response = null;
HttpUtils util;
try
{
util = new HttpUtils(params[0]);
response = util.getContent();
}
catch (Exception e)
{
e.printStackTrace();
response = e.getMessage();
}
return response;
}
#Override
protected void onPostExecute(String result)
{
// Here you can dismiss the ProgressDialog and display the result
}
}
}

What is the best way to use a fragment with httpconnection?

I'm doing the refactoring of an application that uses AsyncTask to make HTTP calls to a web service.
Now use a simple Activity, at the moment when I needs to invoke the service using a AsyncTask in this way:
private class MyAsyncTask extends AsyncTask {<String, Void, Boolean>
private ProgressDialog progressDialog;
private xmlHandler handler;
# Override
protected void OnPreExecute () {
progressDialog = new ProgressDialog (home.This);
progressDialog
. SetMessage (getString (R.string.home_loadinfo_attendere));
progressDialog.setCancelable (false);
progressDialog.show ();
}
# Override
protected Boolean doInBackground (String... params) {
try {
xmlHandler handler = new XmlHandler();
return Service
. GetInstance ()
. CallService (
ServiceType.GETINFO,
Home.This, handler, null);
} Catch (Exception e) {
e.printStackTrace ();
return false;
}
}
# Override
protected void OnPostExecute (Boolean success) {
progressDialog.dismiss ();
String message = null;
if (success | | (handler == null))
message = getString (R.string.server_result_msg500);
else {
switch (handler.getStatusCode ()) {
case 200:
doStuffWithHandler(handler);
return;
case 500:
message = getString (R.string.server_result_msg500);
break;
case 520:
message = getString (R.string.server_result_msg520);
break;
default:
message = getString (R.string.server_result_msg500);
break;
}
}
if (message! = null) {
AlertDialog.Builder builder = new AlertDialog.Builder (home.This);
builder.setTitle (R.string.home_loadinfo_error_title)
. SetMessage (message)
. SetCancelable (true)
. SetNegativeButton (R.string.close_title,
new DialogInterface.OnClickListener () {
# Override
public void onClick (DialogInterface dialog,
int id) {
dialog.cancel ();
}
});
AlertDialog alert = builder.create ();
Alert.show ();
}
}
}
doStuffWithHandler(handler){
// populate interface with data from service
}
I want to do the same but using Android compatibility libraries and FragmentActivity. I read a little about loader but I did not understand how I could use them in this same way, Could you please tell me if this is the right way (FragmentActivity, Fragment and Loader) and how to implement it also addresses giving me examples?
You could create a Loader, something like this:
public abstract class MyLoader extends AsyncTaskLoader<String> {
public MyLoader(Context context) {
super(context);
}
private String result;
protected String error;
#Override
public final String loadInBackground() {
try {
error = null;
// Load your data from the server using HTTP
...
result = ...
...
return result;
}
catch (Exception e) {
Logger.e("ResourceLoader", "Loading resource failed.", e);
error = e.getMessage();
}
return null;
}
#Override
protected void onStartLoading() {
if (!TextUtils.isEmpty(error)) {
deliverResult(result);
}
if (takeContentChanged()) {
forceLoad();
}
}
#Override
public void deliverResult(String data) {
if (isReset()) {
return;
}
result = data;
if (isStarted()) {
try {
super.deliverResult(data);
}
catch(Exception e) {
Log.e("ResourceLoader", "Caught exception while delivering result.", e);
}
}
}
public String getError() {
return error;
}
}
In your Fragment, you can initialize this loader:
public class MyLoaderFragment extends Fragment implements LoaderCallbacks<String> {
....
....
String message;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
....
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, getArguments(), this);
}
#Override
public Loader<String> onCreateLoader(int id, Bundle args) {
return new MyLoader(getActivity());
}
#Override
public void onLoadFinished(Loader<String> loader, String result) {
// Here you have the result in 'result'.
message = result;
...
}
....
}
And instead of just returning a simple 'String' result, you can return any object you like. Just adjust the MyLoader and LoaderCallbacks implementation accordingly.
You can use Asynctask in Fragment exactly as you did in your Activity, few things change, like:
progressDialog = new ProgressDialog (home.This);
change to:
progressDialog = new ProgressDialog (getApplication());
return Service
. GetInstance ()
. CallService (
ServiceType.GETINFO,
Home.This, handler, null);
change to:
return Service
. GetInstance ()
. CallService (
ServiceType.GETINFO,
getApplication(), handler, null);
Anything special to implements Asynctask in Fragment.
I think you need to read more about Fragment itself.

Android can't create handler inside that has not called Looper.loop

i am getting friends list from facebook and populating in list view it works fine but now i am trying to add Progress bar till the list view populates but getting exception i have tried searching but not found solution for my issue, here is my code:
public class FriendsProgress extends AsyncTask<Object, Void, Boolean>
{
#Override
protected Boolean doInBackground(Object... Params)
{
try
{
getFriendList();
friendAdapter = new FriendAdapter(Friends.this, R.layout.activity_friends, friendsList);
Friends.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
list.setAdapter(friendAdapter);
//list.setOnItemClickListener(EditStaff.this);
}
});
}
catch (Exception e)
{
System.out.println("StaffProgess Exception Caught:"+e.getMessage());
}
return Boolean.TRUE;
}
#Override
protected void onPreExecute()
{
friendsProgress=new ProgressDialog(Friends.this);
friendsProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
friendsProgress.setIndeterminate(true);
friendsProgress.setMessage("Loading...");
friendsProgress.setOwnerActivity(Friends.this);
friendsProgress.show();
}
#Override
protected void onPostExecute(Boolean Result)
{
friendsProgress.dismiss();
friendAdapter.notifyDataSetChanged();
}
}
here is getFriendsList function implementation:
public void getFriendList(){
Request request = Request.newMyFriendsRequest(Session.getActiveSession(), new Request.GraphUserListCallback() {
#Override
public void onCompleted(List<GraphUser> users, Response response) {
// TODO Auto-generated method stub
for(int i=0; i<users.size();i++)
{
GraphUser user = users.get(i);
Friend objFriend = new Friend();
objFriend.setFriendID(user.getId());
objFriend.setFriendName(user.getName());
Drawable dd =Friends.LoadImageFromWebOperations("http://graph.facebook.com/" + objFriend.getFriendID() + "/picture");
objFriend.setFriendPic(dd);
//objFriend.setFriendPic("http://graph.facebook.com/" + objFriend.getFriendID() + "/picture");
friendsList.add(objFriend);
//friendAdapter.notifyDataSetChanged();
Log.d("Friend's Id", objFriend.getFriendID());
Log.d("Friend's Name", objFriend.getFriendName());
//Log.d("Friend's Pic", objFriend.getFriendPic());
Log.d("Friend's List Count", Integer.toString(friendsList.size()));
}
}
});
Request.executeBatchAsync(request);
You shouldn't instantiate an Adapter and link it to a ListView inside the doInBackground() method, because it's running on a worker thread, and no operations connected to Android Views are permitted to be executed on a worker thread. Instead you might want to move this code
friendAdapter = new FriendAdapter(Friends.this, R.layout.activity_friends, friendsList);
Friends.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
list.setAdapter(friendAdapter);
//list.setOnItemClickListener(EditStaff.this);
}
});
to the onPostExecute() method. This is surely a better designed solution. Hope this helps.
Try this,
ProgressDialog dialog;
protected void onPreExecute()
{
dialog = new ProgressDialog(Friends.this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMax(100);
dialog.show();
}
Run Ui Thread inside onPostExecute() method as follows :
runOnUiThread(new Runnable() {
#Override
public void run() {
friendAdapter = new FriendAdapter(Friends.this, R.layout.activity_friends, friendsList);
list.setAdapter(friendAdapter);
friendsProgress.dismiss();
friendAdapter.notifyDataSetChanged();
}
});

Disable Buttons during AsyncTask

I programmed an quiz-app and if I touch one of the answers in an AsyncTask if the answer is correct I set the color to green or if it is false to red.
But now during the time the AsyncTask runs I can press other buttons like the "change question" button or on another one of the answers. This is then done after the AsyncTask has finished it's work. So the next question is loaded and it automatically answers the next question or uses one of the jokers what ever.
I tried to setEnabled(false) the Buttons but they are still bugging.
How do I prevent this?
private void disableOrDisableButtons(boolean boo) {
buttonAnswer1.setEnabled(boo);
buttonAnswer2.setEnabled(boo);
buttonAnswer3.setEnabled(boo);
buttonAnswer4.setEnabled(boo);
}
and here I start the AsyncTask
disableOrDisableButtons(false);
new PrepareAdapter().execute(null, null, null);
in my AsyncTask
#Override
protected void onPreExecute() {
disableOrDisableButtons(false);
if (correctAnswerAtButton != buttonClicked) {
switch (buttonClicked) {
case 1:
buttonAnswer1.setTextColor(Color.RED);
break;
case 2:
buttonAnswer2.setTextColor(Color.RED);
break;
case 3:
buttonAnswer3.setTextColor(Color.RED);
break;
case 4:
buttonAnswer4.setTextColor(Color.RED);
break;
}
if (buttonClicked != 0) { // 0.. if second chance joker used
wrongAnswer = true;
}
}
switch (correctAnswerAtButton) {
case 1:
buttonAnswer1.setTextColor(Color.GREEN);
return;
case 2:
buttonAnswer2.setTextColor(Color.GREEN);
return;
case 3:
buttonAnswer3.setTextColor(Color.GREEN);
return;
case 4:
buttonAnswer4.setTextColor(Color.GREEN);
return;
}
}
I you want to disable the whole interface while the AsyncTask runs, you can use code such as the following to display a dialog:
public abstract class BaseAsyncTask<Param, Result> extends AsyncTask<Param, Void, Result> implements DialogInterface.OnCancelListener {
private static final String TAG = "BaseAsyncTask";
private ProgressDialog dialog = null;
protected Context ctx = null;
protected Exception exception = null;
public BaseAsyncTask(Context ctx) {
this.ctx = ctx;
}
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(ctx, WLConstants.MSG_TITLE_LOADING_DIALOG, WLConstants.MSG_LOADING_DIALOG, true);
dialog.setCancelable(true);
dialog.setOnCancelListener(this);
if (ctx instanceof WozzonActivity) {
((WozzonActivity) ctx).setCurrentDialog(dialog);
}
}
#Override
protected Result doInBackground(Param... parameters) {
try {
return inBackground(parameters);
} catch (Exception ex) {
exception = ex;
Log.e(TAG, ex.getClass().getName(), ex);
return null;
}
};
#Override
protected void onPostExecute(Result result) {
try {
dialog.dismiss();
} catch (Exception ex) {
}// TODO:
if (result == null) {
onException(exception);
} else {
onResult(result);
}
}
protected void onException(Exception ex) {
if (ex != null && ex instanceof WozzonException) {
Toast.makeText(ctx, ex.getMessage(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ctx, WLConstants._ERROR_MSG, Toast.LENGTH_SHORT).show();
}
}
public abstract void onResult(Result result);
public abstract Result inBackground(Param... parameters) throws Exception;
#Override
public void onCancel(DialogInterface theDialog) {
cancel(true);
}
}
You need to use the onPreExecute() method of the ASyncTask().
Your problem is not related to threads at all. Try setTextColor(#ff0000) and settextColor(#00ff00), instead of settextColor(Color.RED) and setTextColor(Color.GREEN).
This is the way i use it now to lock my screen during the AsyncTask. For me it is perfect now. Hope it can help u.
private class PrepareAdapter extends AsyncTask<Void, Void, Integer>
implements DialogInterface.OnCancelListener {
private Dialog dialog = null;
#Override
protected void onPreExecute() {
// To disable the whole screen --> setCancelable(false);
dialog = new Dialog(WerWeissWasQuizActivity.this, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dialog.setCancelable(false);
dialog.show();
}
#Override
protected Integer doInBackground(Void... params) {
dialog.dismiss();
return 0;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//do other stuff...
}
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
cancel(true);
}
}

Categories

Resources