I cannot resolve a problem and need your help. When I click on menu I call customer account and then afterwards I close it. Every time I call customer account the memory increases. It should diminish when I close the account, but it does not happen.
Class Menu
mnItemCL_Cust.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
try {
panCenterPrev = (Pane) root.getCenter();
panCenterAct = Customer.listCustomer();
root.setCenter(null);
root.setCenter(panCenterAct);
Customer.btCanc.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
try {
Customer.Fim();
panCenterAct.getChildren().clear();
panCenterAct = null;
root.setCenter(null);
root.setCenter(panCenterPrev);
} catch (Throwable ex) {
Logger.getLogger(Customer.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Class Customer
public class Customer
{
public static Pane listCustomer() throws SQLException, ClassNotFoundException
{
...
final ObservableList<MyCustomer> data = FXCollections.observableArrayList();
...
}
public static class MyCustomer {
private final SimpleIntegerProperty idcl;
private MyCustomer(Integer pIdcl ) {
this.idcl = new SimpleIntegerProperty(pIdcl);
}
public Integer getIdcl() {
return idcl.get();
}
public void setIdcl(Integer pIdcl) {
idcl.set(pIdcl);
}
}
public static void Fim() throws Throwable {
...
rs = null;
tbViewCL.getItems().clear();
tbViewCL = null;
colIDCL.getColumns().clear();
colIDCL = null;
}
...
protected void finalize() throws Throwable {
try{
...
rs.close();
...// Never happens... why??
} catch(Throwable t) {
throw t;
} finally {
JOptionPane.showMessageDialog(null,"End?");
super.finalize();
}
}
Regards
Java usually reclaims the memory you used when it see it fits, so even if you finalize the object, the memory may still be there. However, if rs.Close() never executes, probably is because something before it is throwing and exception, i recommend you to check the code before just to be sure that nothing is doing so, also, if you catch an exception is a good practice to log it so you can know what is happening.
Related
public class OkHttpDns implements Dns {
#NotNull
#Override
public List<InetAddress> lookup(#NotNull String hostname) throws UnknownHostException {
MyLookUpUtility.getInstance.lookup(hostname, new MyLookUpUtility.lookupCallback()
{
#Override
public void onlookupResponseSuccess(JSONObject nslookupResponseJSON) {
Log.d("LookupResponse", nslookupResponseJSON.toString());
}
#Override
public void onlookupResponseFailure(String errCode) {
Log.d("LookupResponse", "Error Code : "+errCode);
}
});
}
}
In the above code, lookup method of DNS interface of OKHttp wants to return immediately. But my custom NSLookupUtility is an asynchronous call and I will have the ip address of the hostname only after a while. How to solve this problem? how to make the synchronous call to wait for the asynchronous call within it ?
Take a look at CompletableFuture. You’ll create an instance in lookup(), kickoff the async lookup, and then call future.get(). When your async call completes, call future.complete().
#Override
public List<InetAddress> lookup(#NotNull String hostName) throws UnknownHostException {
completableFuture = new CompletableFuture<>();
performLookUp(hostName);
try {
String ipAddress = completableFuture.get();
if (ipAddress != null) {
List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ipAddress));
return inetAddresses;
}
} catch (ExecutionException e) {
Log.d(TAG, "Error : ExecutionException : "+e );
e.printStackTrace();
} catch (InterruptedException e) {
Log.d(TAG, "Error : InterruptedException : "+e );
e.printStackTrace();
}
return Dns.SYSTEM.lookup(hostName);
}
private void performLookUp(#NotNull String hostName) {
MyUtiluty.getInstance().lookup(hostName,
new MyCallBack() {
#Override
public void onSuccess(String ip) {
completableFuture.complete(ip);
}
#Override
public void onFailure(String errCode) {
completableFuture.complete(null);
}
});
}
I have a problem with my code, where sometimes I get a null object reference and sometimes not (on the same thing) and I cant understand whats the problem because as I said, one time its working fine but on the second time it shows me the null object reference message. What Im trying to do is to get the club of the logged trainer from my Azure table.
private MobileServiceTable<trainer> TrainerTable=null;
private MobileServiceClient mService=null;
private users cl=null;
private ProgressDialog prg;
private void Trainer_Club_String(final String username)
{
AsyncTask<Void,Void,Void> task = new AsyncTask<Void, Void, Void>()
{
#Override
protected Void doInBackground(Void... voids)
{
try
{
List<trainer> chosen_manager= TrainerTable.where().field("username").eq(username).execute().get(); \\the problem is in this line. Sometimes it tells me that the user is null and sometimes its working well
if(chosen_manager.size()>0)
{
trainer_club=chosen_manager.get(0).getClub().toString();
}
}
catch (Exception e)
{
final String message=e.getMessage().toString();
runOnUiThread(new Runnable()
{
#Override
public void run()
{
Toast.makeText(trainer_home_page.this, message, Toast.LENGTH_LONG).show();
}
});
}
return null;
}
}.execute();
}
ONCREATE:
cl=StaticObjects.GetClient();
trainer_username=cl.getUsername().toString();
Trainer_Club_String(trainer_username);
I have a Observable like this
Observable<String> gitHubRepoModelObservable;
I have this code
repoNames = new ArrayList<String>();
gitHubRepoModelObservable = Observable.fromIterable(repoNames);
repoNames.add("Hello");
gitHubRepoModelObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onNext(String s) {
System.out.println(s);
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
repoNames is just a list of string. When I am adding a string "hello" manually the onNext is getting called but when I am adding string from a API call like bellow
call.enqueue(new Callback<List<GitHubRepoModel>>() {
#Override
public void onResponse(Call<List<GitHubRepoModel>> call, Response<List<GitHubRepoModel>> response) {
for (GitHubRepoModel repo : response.body()) {
repoNames.add(repo.getName());
}
}
#Override
public void onFailure(Call<List<GitHubRepoModel>> call, Throwable t) {
}
});
I am adding strings from the API into the repoNames the "onNext" is not getting called.
I have seen
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
can be added while initializing retrofit but I want to better understand the rxjava so in this experiment it is not working.
Please help!
It can't not be work.
When you create you api request and try subscribe you list is emty, so Observable does not work.
You need to create Observable such, that your subcribe will run your request!
Observable<String> gitHubRepoModelObservable = Observable.create(
new Observable.OnSubscribe<String>() {
#Override
public void call(final Subscriber<? super String> sub) {
call.enqueue(new Callback<List<GitHubRepoModel>>() {
#Override
public void onResponse(Call<List<GitHubRepoModel>> call, Response<List<GitHubRepoModel>> response) {
for (GitHubRepoModel repo : response.body()) {
sub.onNext(repo.getName()); //send result to rx
}
sub.onCompleted();
}
#Override
public void onFailure(Call<List<GitHubRepoModel>> call, Throwable t) {
}
});
}
}
);
gitHubRepoModelObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
#Override
public void onNext(String s) {
System.out.println(s);
}
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
});
Why would onNext get called if you are just adding element to plain List?
In the first example you are seeing onNext being called because modified list is passed through the stream during subscribe.
Create Subject ex. PublishSubject and pass list to Subject.onNext in onResponse, subscribe to it and you will get what you want.
Second option is adding RxJava2CallAdapterFactory and return Observable<Response<List<GithubRepoModel>>>. This way you don't need to create stream yourself.
So I load some data from Database and use SwingWorker for it.
public class LoadFromDatabase extends SwingWorker<ArrayList<Ucet>, GuiUpdate>{
private ArrayList<Ucet> ucty;
private JLabel lblStav;
private File dbPath;
private JProgressBar progress;
private int pocetUctov;
private JButton btnLoad;
private JButton btnStart;
public LoadFromDatabase(ArrayList<Ucet> ucty,JLabel lblStav,File dbpath,JProgressBar progress, JButton btnLoad,JButton btnStart){
this.ucty=ucty;
this.lblStav=lblStav;
this.dbPath=dbpath;
this.progress=progress;
this.btnLoad=btnLoad;
this.btnStart=btnStart;
}
#Override
protected ArrayList<Ucet> doInBackground() throws Exception {
String sqlLoadUcty="SELECT email,password FROM members";
ArrayList<Ucet> ucty2=new ArrayList<>();
try {
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:"+dbPath.getPath());
Statement stmt = conn.createStatement();
stmt.setQueryTimeout(30);
ResultSet rs = stmt.executeQuery(sqlLoadUcty);
GuiUpdate gd=new GuiUpdate(GuiUpdate.GuiType.setStartLoading);
gd.setValue(0);
publish(gd);
pocetUctov=rs.getFetchSize();
gd=new GuiUpdate(GuiUpdate.GuiType.setMaxValue);
gd.setValue(pocetUctov);
publish(gd);
int counter=0;
while (rs.next()){
Ucet uct=new Ucet(
rs.getString("email"),
rs.getString("password")
);
gd=new GuiUpdate(GuiUpdate.GuiType.setValue);
gd.setValue(counter);
publish(gd);
ucty2.add(uct);
}
rs.close();
stmt.close();
conn.close();
} catch (ClassNotFoundException ex) {
System.out.println("Problem= "+ex);
} catch (SQLException ex) {
System.out.println("Problem= "+ex);
}
return ucty2;
}
#Override
public void process(List<GuiUpdate> update){
for (GuiUpdate guiUpdate : update) {
if (guiUpdate.getToDo()==GuiUpdate.GuiType.setStartLoading) {
lblStav.setText("Loading ...");
progress.setVisible(true);
} else if (guiUpdate.getToDo()==GuiUpdate.GuiType.setMaxValue) {
progress.setMaximum(guiUpdate.getValue());
pocetUctov=guiUpdate.getValue();
progress.setMinimum(0);
} else if (guiUpdate.getToDo()==GuiUpdate.GuiType.setValue) {
progress.setValue(guiUpdate.getValue());
}
}
}
#Override
public void done(){
progress.setVisible(false);
btnLoad.setEnabled(true);
try {
ucty=get();
} catch (InterruptedException ex) {
System.out.println("Problem= "+ex);
} catch (ExecutionException ex) {
System.out.println("Problem= "+ex);
}
if (ucty!=null && ucty.size()>0) {
btnStart.setEnabled(true);
lblStav.setText("Loaded "+ucty.size()+" accounts.");
}
}
}
This is whole SwingWorker. I basicly load data from DB and update progress bar.
Once loaded then done() method is called where reference to created ArrayList in doInbackground is set to arraylist which comes from mainGUI and some buttons are allowed and disallowed.
This is how I call SwingWorker from Gui:
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser fileDb=new JFileChooser();
int returnVal=fileDb.showOpenDialog(this);
if (returnVal==JFileChooser.APPROVE_OPTION) {
databasePath=fileDb.getSelectedFile();
jButton4.setEnabled(false);
execurtor.execute(new LoadFromDatabase(naciatneUcty, jLabel9, databasePath, jProgressBar1, jButton4,jButton1));
}
}
This works great ,even if debug last line of code in SwingWorker done() I can clearly see that ArrayList ucty contians data from databse.
Once back to main gui , ArrayList naciatneUcty is still null.
But it should not be since I am sending it to SwingWorker where its reference should be updated...
Where is the problem ,why reference is not updated at all?
Java references are passed by value, so when you execute ucty = get() the reference inside the swingworker is changed, but that isn't going to update the reference for naciatneUcty. You'd be better off instantiating naciatneUcty before running the swingworker, have doInBackground() return void, scrap utcy2 and then just grab utcy in the done() method.
public event EventHandler MyButtonClick = delegate { };
The construction above allows to not check if there is any subscriber:
public virtual void OnMyButtonClick(EventHandler e)
{
this.MyButtonClick(this, e);
}
in stead of
public virtual void OnMyButtonClick(EventHandler e)
{
if (MyButtonClick!=null)
this.MyButtonClick(this, e);
}
But is it really a good idea? Is this the only benefit: to not check if any subscriber exists?
UPDATE: Here is example
namespace ConsoleApplication2
{
public class TestClass
{
public event EventHandler MyButtonClick;
//= delegate { };
public void OnButtonClick(EventArgs e)
{
MyButtonClick(this, e);
}
}
class Program
{
static void Main(string[] args)
{
var testClass = new TestClass();
//it throws an exception
testClass.OnButtonClick(new EventArgs());
// if you add an handler it will call it
testClass.MyButtonClick += myCustomHandler;
testClass.OnButtonClick(new EventArgs()); // myCustomHandler has been invoiked
}
private static void myCustomHandler(object sender, EventArgs e)
{
Console.WriteLine("myCustomHandler has been invoiked");
}
}
}
Well, the code you've given here:
public virtual void OnMyButtonClick(EventHandler e)
{
if (MyButtonClick!=null)
this.MyButtonClick(this, e);
}
isn't thread-safe. If the final subscription is removed after the nullity check but before the invocation, you could end up with a NullReferenceException (depending on whether the "raising" thread sees the change).
So you can change it to this instead:
public virtual void OnMyButtonClick(EventArgs e)
{
var handler = MyButtonClick;
if (handler != null)
{
handler(this, e);
}
}
... but of course you might forget to do that, and even if you don't, it's cumbersome to do that all over the place, IMO. So yes, while the benefit is "only" to avoid the nullity check, I'd say that's not a bad trade-off in many cases. Anything that makes it harder to make mistakes is a good idea, IMO.
Another alternative is to have an extension method:
public static void SafeInvoke(this EventHandler handler, object sender,
EventArgs e)
{
if (handler != null)
{
handler(sender, e);
}
}
Then change your calling code to:
public virtual void OnMyButtonClick(EventArgs e)
{
MyButtonClick.SafeInvoke(this, e);
}
(and use the same code for other events). You'd probably want a generic form for EventHandler<T> as well.
you don't need to do that. If the client that uses you class won't add an handler (subscriber) for MyButtonClick event the code won't throw an exception.
That is how events works (and delegates as there are the same thing) otherwise you would be forced to add an handler to all the events of a class (assuming there are any)
so you can do the below:
public virtual void OnMyButtonClick(EventArgs e)
{
MyButtonClick(this, e);
}
have a look at the example below:
public class TestClass
{
public event EventHandler MyButtonClick = delegate { };
public void ButtonClick(EventArgs e)
{
MyButtonClick(this,e);
}
}
class Program
{
static void Main(string[] args)
{
var testClass=new TestClass();
testClass.ButtonClick(new EventArgs());
// if you add an handler it will call it
testClass.MyButtonClick += myCustomHandler;
testClass.ButtonClick(new EventArgs()); // myCustomHandler has been invoiked
}
private static void myCustomHandler(object sender, EventArgs e)
{
Console.WriteLine("myCustomHandler has been invoiked");
}
}