strange error on my android set frame application - android

i create an application that set a frame to a image bitmap... but when the process give a result, i don't know, why the result bitmap are also saved to my original bitmap variabel, this is my code :
main code :
#Override
public void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.frame);
tampilFrame = (ImageView)findViewById(R.id.ivframe);
oribmp = temporary.getBitmap();
temp = oribmp;
tampilFrame.setImageBitmap(temp);
frame00 = (ImageView)findViewById(R.id.frs00);
frame00.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr00));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
frame01 = (ImageView)findViewById(R.id.frs01);
frame01.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr01));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
frame02 = (ImageView)findViewById(R.id.frs02);
frame02.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr02));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
frame03 = (ImageView)findViewById(R.id.frs03);
frame03.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
frame = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.fr03));
frame = Bitmap.createScaledBitmap(frame, 800, 800, false);
new backtask().execute();
}
});
}
}
the variabel frame00, frame01, frame02 are ImageView that I set as a Button. When the user click the frame image, it will load an image from drawable and stored in a variabel named "frame" and also call a asyncTask named "backtask".
this is the "backtask" code
public class backtask extends AsyncTask<Void, Void, Void> {
ProgressDialog prog;
#Override
protected void onPreExecute(){
super.onPreExecute();
prog = ProgressDialog.show(FrameActivity.this, "", "Progress...");
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
temp = setFrame(oribmp);
Log.i("temp", "widht : "+String.valueOf(temp.getWidth())+" Height : "+String.valueOf(temp.getHeight()));
return null;
}
#Override
protected void onPostExecute(Void res){
super.onPostExecute(res);
tampilFrame.setImageBitmap(temp);
prog.dismiss();
Log.i("setFrame", "Complete");
}
}
this backtask code i used to make a loading progress when the application runs the "setFrame()" code. and this is my "setFrame" code :
public Bitmap setFrame(Bitmap bit){
for (int i=0;i<frame.getWidth();i++){
for(int j=0;j<frame.getHeight();j++){
if (Color.alpha(frame.getPixel(i, j))!=0){
bit.setPixel(i, j, frame.getPixel(i, j));
}
}
}
frame.recycle();
return bit;
}
the oribmp is a variabel that containt original bitmap get from class temporary.getBitmap()
when the "temp = setFrame(oribmp);" finish, the ori bmp has also changes same as the temp.
when i checked to class temporary, the bitmap variabel that contain original bitmap on the temporary class also changes to the result of the setFrame...
this is the code pf temporary class
public class temporary {
private static Bitmap Mbmp;
public static Bitmap getBitmap () {
return Mbmp;
}
public static void setBitmap(Bitmap oribimp) {
// TODO Auto-generated method stub
Mbmp = oribimp;
Log.i("editor", "simpen bitmap");
}
}
temporary class is a class that i used to send the bitmap value to another activity in my application.. this is what the FrameActivity looks like on the run..
strart activity
this is the look of FrameActivity when its first start, the original bitmap is that gecko
set frame 1
this is the looks when set the first frame
set frame 2
this is the looks when set the second frame, cause the oribmp has the same value like the result of the first seFrame, on the second setFrame they looks like pile up
im sory if my question is too long, maybe anyone can give me solution :D

Related

All threads get suspended

I am building an app which will continuously get screenshots of my laptop screen and transfer it to my android app but there is some problem within the while loop, when I put a for loop to a limit then my program runs but as it goes till infinity or I replace it with infinite while loop my code suspends all the threads and app crash dueto memory allocation problem, please suggest me to execute my code infinite times so that there are continuous screenshots displayed.
Thank You.
Here is my code
public class ScreenActivity extends AppCompatActivity {
ImageView img;
int width,height;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen);
img=(ImageView)findViewById(R.id.imageView);
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
// while (true)
for (int i=0;i<100;i++)
new GetImg().execute();
}
Bitmap imgscr;
public class GetImg extends AsyncTask<Object,Void,Bitmap> {
#Override
protected Bitmap doInBackground(Object[] params) {
Socket client= null;
try {
client = new Socket("192.168.1.5",6767);
InputStream in=client.getInputStream();
imgscr=Bitmap.createScaledBitmap(BitmapFactory.decodeStream(in), width, height, false);
} catch (Exception e) {
e.printStackTrace();
}
return imgscr;
}
#Override
protected void onPostExecute(Bitmap bm)
{
img.setImageBitmap(bm);
}
}
}
#m0skit0 commented the actual reason of getting the ANR. You're out of your run-time memory when you're creating threads in an infinite loop. I'm pretty confused about your purpose though. I think you need to get the screenshots one after one and if this is the case, you can simply add a listener to the AsyncTask and get the callback when the screenshot is downloaded fully.
So if I've understood correctly, you need to declare an interface like this.
public interface DownloadCompletedListener {
public void onDownloadComplete(String result);
}
Now you need to implement the interface in your Activity like this
public class ScreenActivity extends AppCompatActivity implements DownloadCompletedListener {
private GetImg getImageTask;
private Bitmap imageBitmap;
#Override
public void onDownloadComplete(String result) {
if(result.equals("SUCCESS")) {
// Set the image now
img.setImageBitmap(imageBitmap);
// Start next download here
getImageTask = new GetImg();
getImageTask.mListener = this;
getImageTask.execute();
} else {
// Do something
}
}
}
You need to modify your AsyncTask a bit. You need to declare the DownloadCompletedListener.
public class GetImg extends AsyncTask<Object,Void,Bitmap> {
private DownloadCompletedListener mListener;
#Override
protected Bitmap doInBackground(Object[] params) {
Socket client= null;
try {
client = new Socket("192.168.1.5",6767);
InputStream in=client.getInputStream();
imgscr=Bitmap.createScaledBitmap(BitmapFactory.decodeStream(in), width, height, false);
} catch (Exception e) {
e.printStackTrace();
}
return imgscr;
}
#Override
protected String onPostExecute(Bitmap bm)
{
imageBitmap = bm;
mListener.onDownloadComplete("SUCCESS");
}
}
So your onCreate function will look like this now
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen);
img=(ImageView)findViewById(R.id.imageView);
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
// Start downloading image here. Remove the loop
getImageTask = new GetImg();
getImageTask.mListener = this;
getImageTask.execute();
}

getWidth() method returns 0

I am building an activity that shows two horizontal scroll views. The top one holds large images while the lower one holds the thumbnails of those images. When the user clicks on a thumbnail the upper scroll view will automatically scroll to the image corresponding to the thumbnail. My problem is that getWidth() method of layout always returns 0. I am creating the layout at runtime and then calling the getwidth() method so it should return the correct value but it is not.
public class ZoomActivity extends Activity {
private final String THUMBS="http://kurdshopping.net/thumbs/";
private final String UPLOADS="http://kurdshopping.net/uploads/";
private ImageView imageView;
private String path;
private String[] filenames;
private LinearLayout l1,l2;
private int[] widths=null;
private HorizontalScrollView hsv=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_zoom);
ActionBarUtils.setActionBar(this);
path = getIntent().getExtras().getString("path");
filenames=getIntent().getExtras().getStringArray("images");
widths=new int[filenames.length];
l1=(LinearLayout) findViewById(R.id.LinearLayout1);
l2=(LinearLayout) findViewById(R.id.LinearLayout2);
hsv=(HorizontalScrollView) findViewById(R.id.horizontalScrollView1);
for(int i=0; i<filenames.length; i++){
BitmapLoaderTask task = new BitmapLoaderTask(i);
task.execute(UPLOADS+filenames[i],"1");
}
for(int i=0;i<filenames.length;i++){
BitmapLoaderTask task = new BitmapLoaderTask(i);
task.execute(THUMBS+filenames[i],"2");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.zoom, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
// case R.id.action_all:
// Intent allitemIntent = new Intent(MainActivity.this,
// AllItemsActivity.class);
// startActivity(allitemIntent);
// break;
// case R.id.action_search:
// Intent search = new Intent(this, SearchDialogActivity.class);
// startActivity(search);
// break;
}
return super.onOptionsItemSelected(item);
}
private void setImageBitmap(Bitmap bmp) {
imageView = new ScrollableImageView(this);
imageView.setLayoutParams(new LayoutParams(bmp.getWidth(), bmp
.getHeight()));
imageView.setImageBitmap(bmp);
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(imageView);
}
private class BitmapLoaderTask extends AsyncTask<String, Void, Bitmap> {
private String layout;
private int index;
private int x_coords=0;
public BitmapLoaderTask(int index){
super();
this.index=index;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
setProgressBarIndeterminateVisibility(true);
}
#Override
protected synchronized Bitmap doInBackground(String... params) {
// AssetManager assets = getAssets();
Bitmap bmp = null;
layout=params[1];
try {
URL url = new URL(params[0]);
bmp = BitmapFactory.decodeStream(url.openConnection()
.getInputStream());
} catch (IOException e) {
Log.e("ZoomActivity", e.getMessage(), e);
}
return bmp;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
View view=null;
try {
view=ImageUtils.insertPhoto(ZoomActivity.this, result);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(layout.equals("1")){
l1.addView(view);
view.setTag(x_coords);
x_coords+=((LinearLayout)view).getMeasuredWidth();// this is always returning 0, view.getLayoutParams().width is also same.
}else{
l2.addView(view);
ImageView img=(ImageView) ((LinearLayout)view).getChildAt(0);
img.setTag(index);
img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int index=(Integer) v.getTag();
LinearLayout layout = (LinearLayout) l1.getChildAt(index);
int x=(Integer) layout.getTag();
hsv.scrollTo(x, 0);
}
});
}
// ImageView imageview=(ImageView) findViewById(R.id.imageView1);
// imageview.setImageBitmap(result);
// setImageBitmap(result);
setProgressBarIndeterminateVisibility(false);
}
}
}
The insertPhoto function where I am creating the layout-
public static View insertPhoto(final Activity activity, Bitmap bm) throws MalformedURLException, IOException {
LinearLayout layout = new LinearLayout(activity.getApplicationContext());
layout.setLayoutParams(new LayoutParams(bm.getWidth()+10, bm.getHeight()+10));
layout.setGravity(Gravity.CENTER);
final ImageView imageView = new ImageView(
activity.getApplicationContext());
imageView.setLayoutParams(new LayoutParams(bm.getWidth(), bm.getHeight()));
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setImageBitmap(bm);
// imageView.setTag(filename);
layout.addView(imageView);
return layout;
}
Thanks in advance for the help.
Edit: I am posting only the portion of the code that needs the width. I modified it to use viewtreeoserver but it still doesn't work -
l1.addView(view);
view.setTag(x_coords);
view.requestLayout();
ViewTreeObserver vto=view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
x_coords+=((LinearLayout)view).getMeasuredWidth();
}
});
Try this code before using get width method-
yourlayout.requestLayout();
Hope this helps you!!!
If it is not working please let me know i will try to help you more.
Edit answer
try this code-
l1.addView(view);
view.setTag(x_coords);
view.requestLayout();
ViewTreeObserver vto=view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
x_coords+=((LinearLayout)view).getMeasuredWidth();
}
});

Android gallery and async loading

I'm trying to load images with an async taks from internet. The problem is that the image will not update. Code:
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i ;
i = new ImageView(this.mContext);
AsycTask task = new AsycTask();
task.url = new URL(mImageIds.get(position));
task.iv = i;
task.execute(i);
return i;
}
public class AsycTask extends AsyncTask<ImageView, Void, Bitmap>{
public Bitmap bm2;
public ImageView iv;
public URL url;
#Override
protected Bitmap doInBackground(ImageView... arg0) {
iv = arg0[0];
try {
bm2 = BitmapFactory.decodeStream((InputStream)url.getContent());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bm2;
}
#Override
protected void onPostExecute(Bitmap result) {
// iv.setImageResource(R.drawable.sw10)
iv.setVisibility(View.VISIBLE);
iv.setBackgroundResource(R.drawable.search);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setImageBitmap(result);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Why isn't the Image updating after I set the Bitmap?
I'm using an async task to update my Image, is this possible?
Try to use UnivsersalImageLoader lib which will simplify your development.
Your code for image loading will be next:
ImageLoader.getInstance().displayImage(imageUrl, imageView); // Default options will be used
UniversalImageLoader

Lazy loading of image in ImageSpan

I want to build custom ImageSpan which set up default picture at the beginning of fetching data and loaded picture when fetching finished.
Example of code:
public class CustomImageSpan extends ImageSpan {
private Drawable mDrawable;
#Override
public Drawable getDrawable() {
if (mDrawable == null) {
mDrawable = defaultDrawable;
Futures.addCallback(
FetchImage.submit(
new FutureCallback<Image>() {
#Override
public void onSuccess(Image result) {
Bitmap bitmap = result.getBitmap();
mDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
//!Rerender span with new bitmap.
}
}, mExecutor);
}
return mDrawable;
}
How to notify span that loading has finished and it`s time to get new bitmap instead of default??
You could try and use a handler to proceed to the next task once the current one has completed
Handler xHandler=new Handler(){
#Override
public void handleMessage(Message message){
switch (message.what){
case SOME_OPERATION:
getImage(); //the method you are using
break;
}
}
};
run the handleer in a seprate thread as below
#Override
public void run() {
xHandler.sendMessage(Message.obtain(xHandler, SOME_OPERATION));
}

How to add at a main layout an imageView controlled from another thread?

I'm making an app for Android. I have reached my goal with the single main thread pushing a button!!! (show an image saved on the SD in an ImageView) But I need to do it with threading to save some time and because I will make other threads.
The problem when I do this on a new thread a warning appears that tells me:
"Only the original thread that created a view hierachy can touch its
views."
And the Image is not opened.
Here is this code:
public class intsocketclient extends Activity implements OnClickListener{
public ImageView imagen;
private Button connectPhones;
private Handler conectarhandler = null;
private Runnable conectarunner = null;
public boolean condicion = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imagen = (ImageView) findViewById(R.id.imagen);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(this);
conectarhandler = new Handler();
conectarunner = new Runnable() {
public void run() {
conectayenvia();
conectarhandler.post(this);
}
};
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub.
if(v==connectPhones) {
new Thread (conectarunner).start();
}
}
public void conectayenvia () {
if (condicion){
condicion = false;
Bitmap bMap = BitmapFactory.decodeFile("/sdcard/recibido.jpg");
imagen.setImageBitmap(bMap);
}
}
}
But I really need it to be this way.
Is it possible to take the main layout (the original "main.xml") and some kind of "add" over it another main file (a "threadmain.xml" which only contains the imageView)but also with the capability of pushing buttons and other kind of things of the first original "main.xml" layout????????
use AsyncTask, as it will handle threads automatically, the preExecute and postExecute methods of AsyncTask run on UI thread.
private class DF extends AsyncTask<Void, Void, Void>{
private Bitmap bMap;
#Override
protected Void doInBackground(Void... params) {
if (condicion){
condicion = false;
bMap = BitmapFactory.decodeFile("/sdcard/recibido.jpg");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
imagen.setImageBitmap(bMap);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
call the asyncTask in onClick.
#Override
public void onClick(View v) {
// TODO Auto-generated method stub.
if(v==connectPhones) {
new DF().execute();
}
}
Your problem is that you're trying to run UI methods not on the UI thread. The solution is to call runOnUiThread from the other thread.

Categories

Resources