顯示具有 Thread 標籤的文章。 顯示所有文章
顯示具有 Thread 標籤的文章。 顯示所有文章

2015年5月8日 星期五

[Android] avoid two different thread call a function in the same time

when two thread call the function of changeThumbnail in the part2, we can make a code like part1 into this function in order to avoid crash.

part1:
isReadyChgPhoto=true;
while(isReadyChgPhoto!=true){
 Log.e("please wait "+i +"sec","wait====================");
 i++;
 SystemClock.sleep(1000);
}
isReadyChgPhoto=false;

part2:
isReadyChgPhoto=true;

private void changeThumbnail(final int index, final int localport){
 new Thread(new Runnable() {
  public void run() {
   int i=0;
   while(isReadyChgPhoto!=true){
    Log.e("please wait "+i +"sec","wait====================");
    i++;
    SystemClock.sleep(1000);
   }
   isReadyChgPhoto=false;
   SystemClock.sleep(1000); 
   VLCApplication.setCurrUID(camIDArr[index]);   //for download thumbnail use
   
   String cmd_snapshot="http://127.0.0.1:"+localport+"/cgi-bin/cgi-cmd.cgi?command=snapshot";
   Log.e("%% get camera thumnail",cmd_snapshot+" uid: "+camIDArr[index]);

   new CGICommandForThumbnail(cmd_snapshot,"snapshot", localport, index).start(); 
   SystemClock.sleep(1000);
   isReadyChgPhoto=true;
   
  }
 }).start();
}

2015年5月5日 星期二

[Android] thread communicate with UI thread by using message

put A part in thread, A part will send messages to main thread(UI thread). That is a way for sub thread to communicate with UI Thread.
A part:
// mainHandler.sendEmptyMessage(0); 
 Bundle result = new Bundle();
 result.putInt("P2Pdone", 1); 
 Message msg = new Message();
 msg.setData(result);
 msg.what = 4; // message number
 mainHandler.sendMessage(msg);

B part:
class MainHandler extends Handler {
  static final int MSGTYPE_LOG =1;
  static final int MSGTYPE_P2PTUNNEL_LOG=2;
  static final int MSGTYPE_P2PLIVE_LOG=3;
  
  @Override
  public void handleMessage(Message msg) {  
   handleMsg(msg);
   super.handleMessage(msg);
  }
  
  void handleMsg(Message msg)
  {
   switch(msg.what){
    case MSGTYPE_LOG:    //1
     _printLog((String)msg.obj);
     break;
    
    case MSGTYPE_P2PTUNNEL_LOG:   //2
     {

     }
     break;
    case MSGTYPE_P2PLIVE_LOG:    //3 , ken
//     txt_log.append(data+"\n");
     txt_log.append(msg.getData().getString("data")+"\n");
     break;  
    case 4:    //4 , ken
     if(msg.getData().getInt("P2Pdone")==1){
      uiSwitch(SC_START);
     }
     
    default:;
   }
  }
 }

2015年3月18日 星期三

[Android] Painless threading (轉貼)


Android offers several ways to access the UI thread from other threads. You may already be familiar with some of them but here is a comprehensive list:


public void onClick(View v) {
  new Thread(new Runnable() {
    public void run() {
      final Bitmap b = loadImageFromNetwork();
      mImageView.post(new Runnable() {
        public void run() {
          mImageView.setImageBitmap(b);
        }
      });
    }
  }).start();
}
Unfortunately, these classes and methods also tend to make your code more complicated and more difficult to read. It becomes even worse when your implement complex operations that require frequent UI updates. To remedy this problem, Android 1.5 offers a new utility class, called AsyncTask, that simplifies the creation of long-running tasks that need to communicate with the user interface.

reference: http://android-developers.blogspot.ru/2009/05/painless-threading.html

[Android] AsyncTask (download picture)

remember to add permission in the manifest.xml , < uses-permission android:name="android.permission.INTERNET" / >

the code as below:

MainActivity.java
package tw.brad.android.book.MyAsyncTask;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity {
 private View start, end, rm_pic;
 private TextView mesg;
 private MyMealTime task;
 private ImageView imView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  start = findViewById(R.id.start);
  rm_pic = findViewById(R.id.rm_pic);
  end = findViewById(R.id.end);
  mesg = (TextView) findViewById(R.id.msg);
  imView = (ImageView)findViewById(R.id.ImageView01);

  start.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    task = new MyMealTime();
    //傳遞多個參數給AsyncTask運作處理
    task.execute("http://spaceflightnow.com/news/n0211/04soho/sun.jpg");
   }
  });
  
  rm_pic.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    // 提早結束AsyncTask
    
    Bitmap tmp = BitmapFactory.decodeResource(getResources(), R.drawable.photo_not_available);
    
    //setImageBitmap=> Sets a Bitmap as the content of this ImageView.是设置其内容
    imView.setImageBitmap(tmp);
    
    //setBackgroundResource => Set the background to a given resource.是设置背景
//    imView.setBackgroundResource(R.drawable.photo_not_available);
   }
  });
  
  end.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    // 提早結束AsyncTask
    if (task != null && !task.isCancelled()) {
     task.cancel(true);
    }
   }
  });
 }

 private class MyMealTime extends AsyncTask< String, Integer, String > {
  private String[] name;
  private boolean isOver;
  int i;

  @Override
  protected String doInBackground(String... names) {
   i=0;
   name = names;
   Log.e("name[0]",name[0]);
   downloadFile(name[0]);
   
   while(true){
    try {
     publishProgress(i++);
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } // 暫停休眠
    
    
    if(i>5){
     break;
    }
    
    // 如果提早結束
    if (isCancelled()) {
     break;
    }
   }
   return null;
  }


  @Override
  protected void onCancelled() {
   super.onCancelled();

  }

  @Override
  protected void onPostExecute(String result) {
   super.onPostExecute(result);
   // 將接收執行結束厚的結果參數顯示在使用者介面
   imView.setImageBitmap(bmImg);
  }

  @Override
  protected void onPreExecute() {
   super.onPreExecute();
  }

  @Override
  protected void onProgressUpdate(Integer... values) {
   super.onProgressUpdate();
   mesg.setText( values[0]+ " sec " );
   if(bmImg!=null){
    imView.setImageBitmap(bmImg);
   }
  }

 }

 private Bitmap bmImg=null;
 private Bitmap downloadFile(String fileUrl){
  URL myFileUrl =null; 
  
  try {
   myFileUrl= new URL(fileUrl);
  } catch (MalformedURLException e) 
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  try {
   HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
   conn.setDoInput(true);
   conn.connect();
   int length = conn.getContentLength();
   int[] bitmapData =new int[length];
   byte[] bitmapData2 =new byte[length];
   InputStream is = conn.getInputStream();
   
   bmImg = BitmapFactory.decodeStream(is);

  } 
  catch (IOException e) 
  {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return bmImg;
 } 
}




activity_main.xml



    

[Android] AsyncTask


Android: How can I pass parameters to AsyncTask's onPreExecute()?
You can override the constructor. Something like:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
 
    public MyAsyncTask(boolean showLoading) {
        super(); 
        // do stuff 
    } 
 
    // doInBackground() et al. 
} 
Then, when calling the task, do something like:
new MyAsyncTask(true).execute(maybe_other_params);

Edit: this is more useful than creating member variables because it simplifies the task invocation. Compare the code above with:
MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
referemce:http://stackoverflow.com/questions/3075009/android-how-can-i-pass-parameters-to-asynctasks-onpreexecute


AsyncTask使用方式如下,

activity_main.xml

    

MainActivity.java
package tw.brad.android.book.MyAsyncTask;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity {
 private View start, end;
 private TextView mesg;
 private MyMealTime task;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  start = findViewById(R.id.start);
  end = findViewById(R.id.end);
  mesg = (TextView) findViewById(R.id.msg);

  start.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    task = new MyMealTime();
    //傳遞多個參數給AsyncTask運作處理
    task.execute("breakfast", "lunch", "dinner");
   }
  });

  end.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    // 提早結束AsyncTask
    if (task != null && !task.isCancelled()) {
     task.cancel(true);
    }
   }
  });

 }

 private class MyMealTime extends AsyncTask < String, Integer, String>{
  private String[] name;
  private boolean isOver;

  @Override
  protected String doInBackground(String... names) {
   name = names;
   for (int i = 0; i < 10; i++) {
    try {
     // 傳遞三個參數處理使用者介面
     publishProgress(i, i + 20, i+40);
     Thread.sleep(1500); // 暫停休眠
     
     // 如果提早結束
     if (isCancelled()) {
      isOver = true;
      break;
     }

    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
   
   // 提早結束傳會null; 否則正常下傳回結果參數
   return isOver?null:"終於執行結束";
  }

  @Override
  protected void onCancelled() {
   super.onCancelled();
   mesg.setText("提早結束");
  }

  @Override
  protected void onPostExecute(String result) {
   super.onPostExecute(result);
   // 將接收執行結束厚的結果參數顯示在使用者介面
   mesg.setText("Result:" + result);
  }

  @Override
  protected void onPreExecute() {
   super.onPreExecute();
  }

  @Override
  protected void onProgressUpdate(Integer... values) {
   super.onProgressUpdate();
   int i = values[0]; 
   String result="";
   if(name[i%3].equals("breakfast")){
    result=name[i%3] + " at 6:" + values[i%3]+" am";
   }else if(name[i%3].equals("lunch")){
    result=name[i%3] + " at 13:" + values[i%3]+" pm";
   }else if(name[i%3].equals("dinner")){
    result=name[i%3] + " at 19:" + values[i%3]+" pm";
   }
   
   // 將執行過程的傳遞參數顯示在使用者介面
   mesg.setText(result);
  }
 }
}