How to wait a thread to be finished - android

Thread b = new Thread(new Runnable() {
#Override
public void run() {
try {
location = relocation();
//log("location success");
} catch (Exception e) {
e.printStackTrace();
}
}
});
b.start();
b.join();
if (location.y>0)
{
location_home.x = 4.5f;
location_home.y = 4.5f;
location_home.theta = (float)Math.PI;
} else
{
location_home.x = -4.5f;
location_home.y = -4.5f;
location_home.theta = 0;
}
I used b.join() to wait a time until var location receive value from relocation to define value for location_home. But its wrong. thread b and if statement running simultaneously. Help me :( tks all

i think it would be good if you use Asyntask in this case:
private class YourThread extends AsyncTask {
#Override
protected Object doInBackground(Object[] params) {
try {
location = relocation();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
//log("location success");
if (location.y > 0) {
location_home.x = 4.5f;
location_home.y = 4.5f;
location_home.theta = (float) Math.PI;
} else {
location_home.x = -4.5f;
location_home.y = -4.5f;
location_home.theta = 0;
}
}
}
and use it :
new YourThread().execute();

Related

AppsFlyer Android onInstallConversionDataLoaded delay callback

Ok so i grabbed the code from AppsFlyer Cordova plugin:
AppsFlyerProperties.getInstance().set(AppsFlyerProperties.LAUNCH_PROTECT_ENABLED, false);
AppsFlyerLib instance = AppsFlyerLib.getInstance();
try{
final JSONObject options = args.getJSONObject(0);
devKey = options.optString(AF_DEV_KEY, "");
isConversionData = options.optBoolean(AF_CONVERSION_DATA, false);
if(devKey.trim().equals("")){
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, NO_DEVKEY_FOUND));
}
isDebug = options.optBoolean(AF_IS_DEBUG, false);
instance.setDebugLog(isDebug);
if(isDebug == true){
System.out.println("AppsFlyer Here 0");
Log.d("AppsFlyer", "Starting Tracking");
}
trackAppLaunch();
instance.startTracking(c.getApplication(), devKey);
if(isConversionData == true){
if(mAttributionDataListener == null) {
mAttributionDataListener = callbackContext;
}
if(mConversionListener == null){
mConversionListener = callbackContext;
}
registerConversionListener(instance);
sendPluginNoResult(callbackContext);
}
else{
callbackContext.success(SUCCESS);
}
}
catch (JSONException e){
e.printStackTrace();
}
registerConversionListener
private void registerConversionListener(AppsFlyerLib instance){
instance.registerConversionListener(cordova.getActivity().getApplicationContext(), new AppsFlyerConversionListener(){
#Override
public void onAppOpenAttribution(Map<String, String> attributionData) {
}
#Override
public void onAttributionFailure(String errorMessage) {
handleError(AF_ON_ATTRIBUTION_FAILURE, errorMessage);
}
#Override
public void onInstallConversionDataLoaded(Map<String, String> conversionData) {
// Delay here up to some minutes
}
OnInstallCoversionDataLoaded callback is delayed up to some minutes. Can anyone advise how to fix this?

Android: AsyncTask giving "skipping x frames" warnings

Im trying to understand how threading works in Android.
I've created this AsyncTask class, but I still get this warning in my console:
Skipped 295 frames! The application may be doing too much work on its main thread.
LoadAnswersTask class
public class LoadAnswersTask extends AsyncTask<String, Void, ArrayList<MessageItemModel>> {
public interface LoadAnswersEventHandler {
void onLoadFinished(ArrayList<MessageItemModel> answers);
}
protected LoadAnswersEventHandler event;
public LoadAnswersTask(LoadAnswersEventHandler event) {
this.event = event;
}
#Override
protected ArrayList<MessageItemModel> doInBackground(String... params) {
try {
QuestionModel q = QuestionModel.getById(Integer.parseInt(params[0]));
ArrayList<MessageItemModel> items = new ArrayList<>();
for (AnswerModel answer : q.getAnswers()) {
MessageItemModel messageItem = new MessageItemModel();
messageItem.message = answer.getComment();
messageItem.id = answer.getId();
messageItem.parentId = answer.getParentId();
messageItem.gender = answer.getGender();
messageItem.name = answer.getName();
messageItem.reply = (answer.getParentId() > 0);
messageItem.email = answer.getEmail();
messageItem.answer = true;
items.add(messageItem);
}
return items;
} catch (Exception e) {
Log.d(getClass().getName(), "Failed to load question", e);
}
return null;
}
#Override
protected void onPostExecute(ArrayList<MessageItemModel> messageItemModels) {
this.event.onLoadFinished(messageItemModels);
}
}
I also tried this approach, which seems to work - well sort of as I have my items in a Fragment inside a viewpager - and it sometimes didn't load the answers, im suspecting it's because of the WeakReference combined with the viewpager causing event.get() to be null, but i'm really not sure...
private static class LoadAnswersHandler extends Handler {
private WeakReference<LoadAnswersEventHandler> event;
public LoadAnswersHandler(LoadAnswersEventHandler event) {
this.event = new WeakReference<>(event);
}
#Override
public void handleMessage(Message msg) {
if(event.get() != null) {
event.get().onLoadFinished((ArrayList<MessageItemModel>) msg.obj);
}
}
}
private LoadAnswersHandler loadAnswersHandler;
// ...
protected void loadAnswers(final LoadAnswersEventHandler event) {
loadAnswersHandler = new LoadAnswersHandler(event);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
QuestionModel q = QuestionModel.getById(question.getId());
ArrayList<MessageItemModel> items = new ArrayList<>();
for (AnswerModel answer : q.getAnswers()) {
MessageItemModel messageItem = new MessageItemModel();
messageItem.message = answer.getComment();
messageItem.id = answer.getId();
messageItem.parentId = answer.getParentId();
messageItem.gender = answer.getGender();
messageItem.name = answer.getName();
messageItem.reply = (answer.getParentId() > 0);
messageItem.email = answer.getEmail();
messageItem.answer = true;
items.add(messageItem);
}
loadAnswersHandler.sendMessage(Message.obtain(loadAnswersHandler, UPDATE_UI, items));
} catch (Exception e) {
Log.d(getClass().getName(), "Failed to load question", e);
}
}
});
thread.start();
}
Thanks!
- Simon

How to fix "android.view.ViewRootImpl$CalledFromWrongThreadException"

I want to fix error as follows:
"android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views."
here are my code.
public class MainActivity extends Activity {
#SuppressLint("NewApi") #Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
onShowMessage();
}
public void removeContent() {
LinearLayout list = (LinearLayout) findViewById(R.id.linearlayout_list);
list.removeAllViews();
}
public void onShowMessage() {
Thread myThread = new Thread(new Runnable() {
#Override
public void run() {
String id = "id1";
String message = "message1";
String response = HTTPUtils.HTTPPost(Global.MESSAGE_URL,
"id", id,
"message", message);
process(response);
}
});
myThread.start();
}
private void process(String response) {
if (response == null || response.equals("")) {
return;
} else {
try {
JSONObject json = null;
try {
json = FbUtil.parseJson(response);
} catch (FacebookError e) {
showErrorMessage();
}
if (json.has("exception")) {
showErrorMessage();
return;
} else {
Global.list = JsonParser.getInfo(json);
removeContent();
initView();
return;
}
} catch (JSONException e) {
}
return;
}
}
}
error occur on removeContent();
please help me.
You are updating Views in a different thread
removeContent();
initView();
Call this two methods in a UI thread like.
runOnUiThread(new Runnable() {
#Override
public void run() {
removeContent();
initView();
}
});

AsyncTask, doInBackground doesn't seem to work

I have that AsyncTask code
public class DiceTask extends AsyncTask<Socket, Void, int[]> {
private int[] arrayFromServer = new int[8];
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected int[] doInBackground(Socket...params) {
Socket soc = params[0];
try {
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
int[] tempArray = (int[]) (ois.readObject());
return tempArray;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onProgressUpdate(Void...arg1) {
}
#Override
protected void onPostExecute(int[] result) {
arrayFromServer = result;
}
public int[] getTempDice() {
return arrayFromServer;
}
}
where is called this way into my main thread.
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
task.execute(socket);
tempArray = task.getTempDice();
printDice(tempArray,pDice);
clickableDice(pDice);
}
});
where I am getting a null tempArray. If I change my onPreExecute to this
#Override
protected void onPreExecute() {
super.onPreExecute();
for(int i = 0; i < arrayFromServer.length; i++) {
arrayFromServer[i] = 1;
}
}
I am getting my dice as it should, all are one. The code I am running into the rollDice() is this
public void rollDice() {
try {
DataOutputStream sout = new DataOutputStream(socket.getOutputStream());
String line = "dice";
PrintStream out = new PrintStream(sout);
out.println(line);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
and I can see the results in the server.
You don't need to implement onPostExecute in your AsyncTask class definition. You also don't need the getTempDice function. You just need to override onPostExecute in an anonymous class and run your UI code in it.
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
task = new DiceTask() {
#Override
public void onPostExecute(int[] result) {
tempArray = result;
printDice(tempArray,pDice);
clickableDice(pDice);
}
}.execute(socket);
}
});
Children of AsyncTask run in parallel with main Thread, you are trying access the attribute arrayFromServer right after to start the Thread. It's recommended you use a callback to retried the value wanted, making sure you get the value after Thread is done.
Making the follow changes can solve your problem. Let me know if you understand.
public class DiceTask extends AsyncTask<Socket, Void, int[]> {
public interface Callback {
void onDone(int[] arrayFromServer);
}
private Callback mCallback;
public DiceTask(Callback c) {
mCallback = c;
}
#Override
protected int[] doInBackground(Socket...params) {
Socket soc = params[0];
try {
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
int[] tempArray = (int[]) (ois.readObject());
return tempArray;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(int[] result) {
mCallback.onDone(result);
}
}
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
new DiceTask(new Callback() {
public void onDone(int[] tempArray) {
printDice(tempArray,pDice);
clickableDice(pDice);
}
}).execute(socket);
}
});

Background Service Hangs UI upto the time web service finish its execution?

I have created a webservice class lokks like below, in with in the "onCreate" method of the service i Have called my webservice which takes around 45 seconds to complete its execution for that time my UI gets black that means it Hangs upto the execution of the web service,
below is the code of my service,
public class productService extends Service
{
private static Context _pctx;
static Vector _productsAll = null;
public static void getInstance(Context context) throws Exception
{
if (_pctx == null)
{
_pctx = context;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
try
{
LoadAllProducts();
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
return START_REDELIVER_INTENT; // 21 sec
}
#Override
public void onDestroy()
{
_productsAll= null;
}
private void LoadAllProducts() throws Exception
{
_productsAll = new Vector();
Exception e = null;
WebResponse myResponse = DataService.GetData("$PR$" , _pctx);
if (Helper.getBoolValueFromString(myResponse.Success))
{
saveMDBData(myResponse.Response);
}
else
{
e = new Exception(myResponse.Response.toString());
}
//cats = null;
if (e != null) {
throw e;
}
}
public static void saveMDBData(StringBuffer pMDBData)
{
Vector Rows;
Vector Cols;
int iRow = 0;
if (pMDBData != null)
{
if (!pMDBData.toString().trim().equals(""))
{
Rows = Helper.getRowsNew(pMDBData);
if (Rows != null)
{
for (iRow = 0; iRow < Rows.size(); iRow++)
{
if (!((String) Rows.elementAt(iRow)).trim().equals(""))
{
Cols = Helper.SplitMultiCharDelimiters((String) Rows.elementAt(iRow), Helper.FIELDDELIMITERS);
assignMDBData(Cols);
}
}
}
}
}
Rows = null;
Cols=null;
}
private static void assignMDBData(Vector pCols)
{
Product myProduct = null;
if (pCols != null)
{
//Create new setting instance
//myProduct = new Product();
myProduct = new Product();
//assign values
myProduct.Id = Helper.getIntValue((String)pCols.elementAt(0));
myProduct.PartNumber = (String)pCols.elementAt(1);
myProduct.Description = (String)pCols.elementAt(2);
myProduct.IdCategory = Helper.getIntValue((String)pCols.elementAt(3));
myProduct.Ideal = Helper.getIntValue((String)pCols.elementAt(4));
myProduct.Taxable = Helper.getBoolValueFromString((String)pCols.elementAt(5));
myProduct.Discountable = Helper.getBoolValueFromString((String)pCols.elementAt(6));
myProduct.LotSize = Helper.getIntValue((String)pCols.elementAt(7));
myProduct.RetailPrice = Helper.getDoubleValue((String)pCols.elementAt(8));
myProduct.ListPrice = Helper.getDoubleValue((String)pCols.elementAt(9));
myProduct.TotalOnHand = Helper.getIntValue((String)pCols.elementAt(10));
myProduct.TotalOnOrder = Helper.getIntValue((String)pCols.elementAt(11));
myProduct.IsPrepack = Helper.getBoolValueFromString((String)pCols.elementAt(12));
//myProduct.Breakdown = (String)pCols.elementAt(13);
myProduct.NoInventory = Helper.getBoolValueFromString((String)pCols.elementAt(13));
myProduct.IsCollection = Helper.getBoolValueFromString((String)pCols.elementAt(14));
myProduct.Followup = Helper.getIntValue((String)pCols.elementAt(15));
myProduct.PctDiscount = Helper.getDoubleValue((String)pCols.elementAt(16));
myProduct.IdGroup = Helper.getIntValue((String)pCols.elementAt(17));
myProduct.Points = Helper.getIntValue((String)pCols.elementAt(18));
myProduct.IsVitamin = Helper.getBoolValueFromString((String)pCols.elementAt(19));
myProduct.PusChange = Helper.getIntValue((String)pCols.elementAt(20));
myProduct.MovedToCloseout = Helper.getDateDataSync((String)pCols.elementAt(21));
myProduct.OnHandDelta = Helper.getIntValue((String)pCols.elementAt(24));
//save processed setting to persistent collection
_productsAll.addElement(myProduct);
//release saved setting in)stance
myProduct = null;
}
}
}
Anyone please help me to sort out the probelm,
I am Stuck Here,
Thanks in Advance!
For Background Services use the AsyncTask which creates background threads so doesn't effect your main UI.
Here is the Code:
public class DownloadData extends AsyncTask<String, String, String> {
#Override
public void onPreExecute() {
// Do Some Task before background thread runs
}
#Override
protected String doInBackground(String... arg0) {
// To Background Task Here
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
// publish progress here
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Do some Task after Execution
}
}
For more details: See this one
http://developer.android.com/reference/android/os/AsyncTask.html

Categories

Resources