how to save image onSaveInstanceState when rotate screen ? - imageview

I'm downloading an image to image view by AsyncTask and I want to save my image when I'm rotate my phone and not to download again to image view...
public void onSaveInstanceState(Bundle toSave) {
super.onSaveInstanceState(toSave);
my_image.buildDrawingCache();
Parcelable bm = my_image.getDrawingCache();
toSave.putParcelable("savedImage", bm);
}
i'm trying to understand if I'm doing something wrong with onSaveInstanceState or not, and how do I retrieve this state onRestoreInstanceState and place the image without downloading again ...

onSaveInstanceState() function has to be used for saving small objects, not for heavy objects.
If you want to save heavy images on phone rotation, then use any of below techniques:
If you want to save large objects use onRetainNonConfigurationInstance() function.
Or else we can make that image as static, so that the image will be loaded only once.
Meaning: On downloading an image from network, make it pointed by a static variable.
If user rotates the phone, since android kills that activity and recreates it, just
put a if condition check if that static variable is not null, then only download again.
As you know static variables will be created only once, it will not download again.
But preferably go for 1st option.
Ref : developer android official tutorial

First of all super.onSaveInstanceState(toSave) should be at the last place in method onSaveInstanceState(Bundle toSave).
In onCreate(Bundle savedInstanceState) check, if savedInstanceState is not null and get what you want:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
if(savedInstanceState != null){
...
...savedInstanceState.getParcerable(...);
...
}
}

Don't use static variables to hold onto bitmaps.

Related

Adding type to a document uploaded in Alfresco through behaviour

I am trying to associate a document type to xz:xylo, whenever a document is uploaded in a particular workspace of Alfresco, it should get attached to a type which I defined in xylomodel.xml.
I am trying to achieve this via Alfresco behaviour as procceding via Share has some limitation for my requirement.
Can anyone please correct me if the code attached is syntactically correct and I am approaching correctly.
enter code here
public class ApplyXyloAspect implements NodeServicePolicies.OnCreateNodePolicy {`
private NodeService nodeService;
private PolicyComponent policyComponent;
// Behaviours
private Behaviour onCreateNode;
}
/**
^When a document of type #XyloCmsType(name = "X:xz:Xylo") is created than aspects from xyloModel.xml
^needs to be applied
*/
public void init() {
// Create behaviours
if workspace=workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg
org.alfresco.repo.node.NodeServicePolicies this.onCreateNode = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT);
// Bind behaviours to node policies
this.policyComponent.bindClassBehaviour(Qname.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
Qname.createQName(XYLO.NAMESPACE_XYLO_CONTENT_MODEL, XYLO.TYPE_xz_xyloModel),
this.onCreateNode
);
}
Depending on your requirements you might be better off achieving this through Folder Rules.
If folder rules are not adequate, or if I'm misunderstanding your use of the very specific NodeRef of workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg then I would just check in the onCreateNode method if the created node's parent matches that NodeRef, rather than trying to check in the init method.
so in your init method you would just do something like this:
this.onCreateNode = new JavaBehaviour(this, "onCreateNode", Behaviour.NotificationFrequency.FIRST_EVENT);
this.policyComponent.bindClassBehaviour(NodeServicePolicies.OnCreateNodePolicy.QNAME, Qname.createQName(XYLO.NAMESPACE_XYLO_CONTENT_MODEL, XYLO.TYPE_xz_xyloModel), this.onCreateNode);
And then just check if the node is a child of the node you're trying to have be the parent, in this case you said it would be workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg.
So the onCreateNode method would look something like this.
#Override
public void onCreateNode(ChildAssociationRef childAssociationRef){
NodeRef idealParentNodeRef = new NodeRef("workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg");
NodeRef nodeRef = childAssociationRef.getChildRef();
NodeRef parentRef = childAssociationRef.getParentRef();
//First double check and make sure all the nodes exist.
if(nodeService.exists(nodeRef) && nodeService.exists(parentRef) && nodeService.exists(idealParentNodeRef)){
//then check if the parentRef and the idealParentNodeRef match
if(parentRef.equals(idealParentNodeRef)){
nodeService.addAspect(nodeRef, /*QName of the Aspect you want to add*/);
}
}
}
If you know for a fact the node/workspace you're uploading to will be very specific every time you could just do this, though I would probably also suggest throwing in some error handling, logging, etc. but this would get you started at least.
Note that, generally, you shouldn't necessarily expect the NodeRef to stay the same every time, granted, I'm just showing you what you could do based on the information from your post rather than what you should do (which would be finding some other way to reference the NodeRef/workspace you're trying to use, and going on from there, depending on whether that NodeRef/workspace is a Folder or Site, or something else).
Hope this helps.

Unity - GameObject.Find() works only on server

I am making a simple networking game. The scene has a button named 'ReloadButton' and i am trying to find this button and add a listener to it through my script attached on the player.
private Button reloadBtn;
void Start()
{
GameObject tempGO = GameObject.Find("ReloadButton");
if (tempGO != null)
{
reloadBtn = tempGO.GetComponent<Button>();
reloadBtn.onClick.AddListener(weaponManager.Reload);
}
}
I am doing it this way because direct referencing of 'ReloadButton' to the script through public Buttonvariable is not possible.
The code works fine on the server, the listener is also added correctly. but on the client, the GameObject.Find("ReloadButton") throws a NullReferenceException.
Seems like the client cannot find the Button itself.
I cannot proceed further in my project without solving this problem, I hope some of you can point me towards the problem.

RequestCode changes along the way

I have a fragment within a fragment
both fragments load fine, except in one of the fragments i have a start camera intent with activity for result
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQ_TAKE_PHOTO);
}
now my REQ_TAKE_PHOTO is defined as follows :
public static final int REQ_TAKE_PHOTO=301;
however, in my onActivityResult the request code i get when returning from the camera intent is
131373 -> not the code i sent the request with
what could be changing the code along the way ?
note that when the inner fragment (the one that is incharge of taking the picture) is run separately, the code returns as 301 normally
to make the requestCode be what it was when i started the startActivityForResult
I need to do requestCode&0xffff
This is apparently a bug in the android support library
according to this: https://code.google.com/p/android/issues/detail?id=15394

How to deal with FragmentPagerAdapter reusing Fragments?

So, I'm trying to use a ViewPager from Android's support v4 library, but there's some serious issues with how it (or FragmentPagerAdapter) deals with Fragments. For instance, I subclassed FragmentPagerAdapter to do the following:
public class MyPagerAdapter extends FragmentPagerAdapter
{
private ArrayList<Fragment> fragments = null;
private ArrayList<Data> data = null;
public MyPagerAdapter(FragmentManager fragmentManager, ArrayList<Data> data)
{
super(fragmentManager);
this.data = data;
fragments = new ArrayList<Fragment>();
for(Data datum : data)
{
MyDataFragment fragment = new MyDataFragment();
fragment.setData(datum);
fragments.add(fragment);
}
}
#Override
public Fragment getItem(int i)
{
return fragments.get(i);
}
#Override
public int getCount()
{
return fragments.size();
}
}
Now, I thought this would be sufficient, and that I could go on and implement MyDataFragment using the onCreateView method that Fragments typically implement. But I ran into an interesting problem. When I would navigate away from the Activity, and then back to it, the ViewPager would appear blank. Somehow, it was reusing Fragments by calling findFragmentByTag, then simply not even calling getItem, etc. What's worse, the Fragment would get no onCreateView event. So I figured I could utilize the ViewPager's Fragment caching by moving my onCreateView code, which primarily grabs references to the various Views the fragment inflates, to onAttach. The only problem is, that during onAttach, MyDataFragment's getView method always returns null. All of the examples for Fragments online describe that onCreateView should have all of your view setup code. Ok, fine. But then, when I create a method like MyDataFragment.setSomeField(String value), I need to use a reference to a TextView. Since onCreateView doesn't always get called (like, when Fragments are magically recycled by FragmentPagerAdapter, for instance), it's better to grab that reference in onAttach. However, during onAttach, the root view for the Fragment is still null (probably because onCreateView wasn't called in the first place)! No additional events happen after that (with the exception of onActivityCreated, which has nothing to do with the Fragment itself), so there's no place to do setup code. How is this supposed to work? Am I missing something important here, or was the Fragment system designed by a monkey?
I'm not sure that this is the right use case for a FragmentPagerAdapter (it sounds more like something you'd want to do with a ListAdapter).
From the FragmentPagerAdapter docs:
Implementation of PagerAdapter that represents each page as a Fragment
that is persistently kept in the fragment manager as long as the user
can return to the page.
This version of the pager is best for use when there are a handful of
typically more static fragments to be paged through, such as a set of
tabs. The fragment of each page the user visits will be kept in
memory, though its view hierarchy may be destroyed when not visible.
This can result in using a significant amount of memory since fragment
instances can hold on to an arbitrary amount of state. For larger sets
of pages, consider FragmentStatePagerAdapter.
I'd consider switching to the FragmentStatePagerAdapter or perhaps a ListAdapter.
If you want the createView to be called it will have to be recreated each time (destroy the old fragment and create new ones), but again I don't think that's quite what you want.

Automatically read a file - easy

This should be a really easy question, but I just cant seem to get it done, I have a section of code calculating X Y points on a graph, then saving them to file.
If a certain condition is met I want to plot the values on a graph, I am using this code to plot the graph- http://www.kodejava.org/examples/805.html
But I don't want it to ask for the user to point to the file location, I just want it to open a file which has a directory hard coded in, and plot it automatically. So basically remove the buttons at the top and carry out the commands of the buttons automatically.
Would be fantastic if somebody could point me in the right direction, I'm a physicist not a coding expert so as much help as possible would be excellent.
Hope I can help one of you in return sometime.
1) Inside public static void main, just above frame.setVisible(true); insert openButton.setVisible(false);
2) Inside class GraphPanel, inside the method public void actionPerformed(ActionEvent e) insert datapanel.actionPerformed(e); as the first line.
3) Inside class DataPanel inside public void actionPerformed comment out from the beginning JFrame fileFrame = new JFrame(); to initialized = readFile(datafile);
4) Just after the comment, insert initialized = readFile(new File("path_to_data_file"));
Now if you open, and press plot, the hard coded file will be read and plot will be drawn.
Heck,, I don't care if this gets downvoted :). I've never touched Java. After reading your problem, specially I'm a physicist not a coding expert first i searched in google how to compile and run a java file. Then started reading the java program. I even made another version which does not need the button press also, Just open and your graph will be drawn. But that's only if needed, then provided. "Welcome to my java attempt" :)
Update:
For doing without pressing plot, in GraphPanel and DataPanel, and rename the actionPerformed methods to something else like GraphPanel::start_working and DataPanel::start_working Now inside GraphPanel::start_working call DataPanel::start_working instead of earlier datapanel.actionPerformed(e); . If compiler cribs, add some empty actionPerformed for compilation. (perhaps we can remove the implements ) Now your flow is ready without any user action. you just need to start it. So you set plotButton.setVisible(false); to hide the plot button and call graphpanel.start_work(); to start the flow in main.
Update:
Inside GraphPanel
public void start_working() {
datapanel.start_working()
if (!datapanel.isInitialized()) {
return;
}
datapanel.refreshData();
panel.setDisplayPlot(true);
panel.update(panel.getGraphics());
frame.setSize(700, 600);
frame.setVisible(true);
frame.pack();
}
And inside DataPanel
public void start_working(ActionEvent e) {
initialized = readFile(new File("PATH_TO_FILE");
panel.update(panel.getGraphics());
frame.pack();
frame.setVisible(true);
}
in main last 5 lines
openButton.setVisible(false);
plotButton.setVisible(false);
graphpanel.start_working();
frame.setVisible(true);
frame.pack();

Resources